2012-08-15 3 views
-1

메서드를 내 장고 양식에서 오버 라이드하는 방법을 알아 내려고 노력하여 데이터베이스의 추가 값을 포함하려고합니다. 나는 사용자를위한 양식 옵션으로 나열하려고하는 사진 작가 그룹이 있습니다. 그런 다음 사용자의 사진 작가 선택이 새 모델의 인스턴스로 생성되어 다른 정보와 함께 데이터베이스에 추가됩니다.오버 라이드 __init__ : 폼 확장 (Python/Django)

이것은 내 Current Question의 계속 또는 정교화입니다. @ Rob Osborne은 BaseForm을 확장하는 방법을 이해하는 데 도움이되는 훌륭한 조언을 해 주었지만 여전히 실행 코드를 가져올 수 없습니다. 관심이있는 경우 연결된 질문에 내 모델, 양식 및보기가 나열됩니다. ModelForm을 사용하는 것이 더 쉽고 문서화되었다는 것을 알고 있지만이 경우 BaseForm을 사용해야합니다.

class AForm(BaseForm): 
    def __init__(self, data=None, files=None, instance=None, auto_id='id_%s', 
       prefix=None, initial=None, error_class=ErrorList, 
       label_suffix=':', empty_permitted=False): 

     self.instance = instance 
     object_data = self.instance.fields_dict() 
     self.declared_fields = SortedDict() 
     self.base_fields = fields_for_a(self.instance) 

     BaseForm.__init__(self, data, files, auto_id, prefix, object_data, 
         error_class, label_suffix, empty_permitted) 
     self.fields['photographer'].queryset = Photographer.objects.all() 

    def save(self, commit=True): 
     if not commit: 
      raise NotImplementedError("AForm.save must commit it's changes.") 

     if self.errors: 
      raise ValueError(_(u"The Form could not be updated because the data didn't validate.")) 

     cleaned_data = self.cleaned_data 

     # save fieldvalues for self.instance 
     fields = field_list(self.instance) 

     for field in fields: 
      if field.enable_wysiwyg: 
       value = unicode(strip(cleaned_data[field.name])) 
      else: 
       value = unicode(cleaned_data[field.name]) 

KeyError at 'photographer'에 위의 코드 결과를 사용 : 여기

내가 가진 것입니다.

photographer 값을 얻을 수 있도록이 KeyError 문제를 해결하는 방법에 대한 아이디어 나 의견을 보내 주시면 감사하겠습니다. 고맙습니다!


편집 :

가 @supervacuo에서 권장하는대로, 슈퍼를 사용하려고하지만, 여전히 점점 KeyError at photographer 이전과 : 나는이 KeyError를 생성한다 누락 될 수 무엇

class AForm(BaseForm): 
    def __init__(self, data=None, files=None, instance=None, auto_id='id_%s', 
      prefix=None, initial=None, error_class=ErrorList, 
      label_suffix=':', empty_permitted=False): 

     super(AForm, self).__init__(data, files, auto_id, prefix, object_data,       error_class, label_suffix, empty_permitted) 
     self.fields['photographer'].queryset = Photographer.objects.all() 

? 어떤 조언을 주셔서 감사합니다.


편집 2 : models.py에서 fields_dict()

어떤 조언을

class A(models.Model): 
    category = models.ForeignKey(Category) 
    user = models.ForeignKey(User) 

    def fields_dict(self): 
     fields_dict = {} 
     fields_dict['title'] = self.title 

     for key, value in self.fields(): 
      fields_dict[key.name] = value.value 

     return fields_dict 

감사를 추가.


EDIT 3 (기타 정보를 포함 할뿐만 아니라, 초기에 상기 질문 class AForm 편집)

def fields_for_a(instance): 
    fields_dict = SortedDict() 
    fields = field_list(instance) 

    for field in fields: 
     if field.field_type == Field.BOOLEAN_FIELD: 
      fields_dict[field.name] = forms.BooleanField(label=field.label, required=False, help_text=field.help_text) 
     elif field.field_type == Field.CHAR_FIELD: 
      widget = forms.TextInput 
      fields_dict[field.name] = forms.CharField(label=field.label, required=field.required, max_length=field.max_length, help_text=field.help_text, widget=widget) 

      fields_dict[field.name] = field_type(label=field.label, 
              required=field.required, 
              help_text=field.help_text, 
              max_length=field.max_length, 
              widget=widget) 

    return fields_dict 

EDIT 4 DEF 필드 (자기). models.py의

def fields(self): 
     fields_list = [] 
     fields = list(self.category.field_set.all()) 
     fields += list(Field.objects.filter(category=None)) 

     for field in fields: 
      try: 
       fields_list.append((field, field.fieldvalue_set.get(ad=self),)) 
      except FieldValue.DoesNotExist: 
       pass # If no value is associated with that field, skip it. 

     return fields_list 

    def field(self, name): 
     if name == 'title': 
      return self.title 
     else: 
      return FieldValue.objects.get(field__name=name, ad=self).value 
+0

과 같이 fields_dict() 메서드를 편집해야합니다. ModelForm 또는 일반 폼을 사용하고 있습니까? 원래 질문에서 명확하지 않습니다. 일반 양식을 사용하는 경우 필드를 양식에 추가해야합니다. –

+0

ModelForm이 아닌 BaseForm을 사용하고 있습니다. 댓글 주셔서 감사합니다. [이것은 링크입니다] (http://docs.nullpobug.com/django/trunk/django.forms.forms.BaseForm-class.html) BaseForm 정보. django의 소스 BaseForm 클래스에 대한 링크입니다. (https://github.com/django/django/blob/master/django/forms/forms.py). 어떤 아이디어 주셔서 감사합니다. –

+0

음, 나는 투표하지 않았다. 나는 당신이 사용하고 있는지 확실하지 않았습니다 –

답변

1

귀하의 질문에의 GitHub 링크가 먼저 되었습니다.

django-classifieds application에는 FieldFieldValue 모델을 기반으로하는 전체 동적 시스템 필드가있어 문제가 발생했습니다. django-classifieds의 이러한 측면을 완전히 이해하지 못했다면 프로젝트를 다른 것을 기반으로하는 것이 좋습니다.

django-classifiedmodels.py에서 FIELD_CHOICES의 목록을 아래를 내려다 보면서, 당신은 relationsips를 정의하려면이 데이터베이스 기반 필드 시스템을 사용할 수 없습니다 - 그래서 동적 별 카테고리 ForeignKey 필드가 없습니다!

A 모델에 photographer 필드를 추가하는 것입니다 (다른 이름을 Ad에서 변경 한 특별한 이유가 있습니까?). 다른 질문에 근거한 것처럼 보입니다. 나머지 거리로 이동하려면

def fields_dict(self): 
    fields_dict = {} 
    fields_dict['title'] = self.title 
    fields_dict['photographer'] = self.photographer 

    for key, value in self.fields(): 
     fields_dict[key.name] = value.value 

    return fields_dict 
+0

대단히 감사합니다 @ supervacuo. 아주 철저한 설명. 내 질문을 끓이고 단순화하려는 노력에서 나는 이해하기가 훨씬 더 어려워졌습니다. 혼란에 대해 사과 드리며, 자세히 설명해 주셔서 감사합니다. 이 교훈적인 과정은 나에게 많은 지식을 부여했으며, 그것에 대해 감사드립니다. –

1

BaseForm.__init__으로 전화하는 것이 잘못되었습니다. (실제로는 다른 질문에 롭 오스본의 허용 대답에 권장) 그렇게

class AForm(BaseForm): 
    def __init__(self, *args, **kwargs): 

     super(AForm, self).__init__(*args, **kwargs) 
     self.fields['photographer'].queryset = Photographer.objects.all() 

처럼 super()를 사용한다.

너머에 나는 fields_dict() 메쏘드를 의심 스럽다. 장고는 장고에 속하지 않으며 그 정의를 제공하지 않았다. print self.fields.keys()으로 확인하십시오. 신비한 이유가 무엇이든 photographer이 없으면 fields_dict()의 코드를 게시하십시오.

+0

답장을 보내 주셔서 감사합니다 @ supervacuo. 위 질문에 대한 편집에서 설명한대로'super()'구현을 시도했습니다. 불행히도, 나는 아직도 사진 작가에게 'KeyError'가있는 이유를 알 수 없습니다. 이 문제를 해결하는 데 도움이되는 아이디어가 있습니까? 대단히 감사합니다 –

+0

제 대답의 두 번째 부분을 읽어주십시오. 질문에'fields_dict()'에 대한 코드를 추가하십시오. – supervacuo

+0

위 질문에'fields_dict()'를 추가했습니다. 조언을 주셔서 감사합니다 @ supervacuo. –