-1

努力弄清楚如何__init__()在我的 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'.

我很欣赏有关如何解决此 KeyError 的任何想法/评论,以便我可以将这些photographer值放入我的表单中。谢谢!


编辑:

正如@supervacuo 推荐的那样,尝试使用super,但仍然KeyError at photographer像以前一样获得:

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()

生成 KeyError 时我会遗漏什么?感谢您的任何建议。


编辑2:添加fields_dict()

来自模型.py

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

感谢您的任何建议。


编辑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

编辑 4:定义字段(自我)。来自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
4

2 回答 2

1

您的呼叫BaseForm.__init__似乎是错误的;你应该使用super(),像这样

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

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

(正如 Rob Osbourne 对您的其他问题所接受的答案中所建议的那样)。

除此之外,我怀疑你的fields_dict()方法,它不是 Django 的一部分,你没有提供定义。确认print self.fields.keys(),无论出于何种神秘原因,photographer不存在,然后发布fields_dict().

于 2012-08-15T16:34:23.863 回答
1

该 GitHub 链接应该是您问题中的第一件事

django-classifieds应用程序具有完整的动态字段系统(基于FieldFieldValue模型),这就是您遇到麻烦的原因。如果您不完全理解django-classifieds.

查看FIELD_CHOICESindjango-classified的列表models.py,您不能使用这个数据库驱动的字段系统来定义关系 - 所以没有动态的每个类别ForeignKey字段!

另一种方法是在您的模型上添加一个photographer字段A(您将其重命名的任何特定原因Ad?),因为您似乎已经根据您的其他问题完成了。但是,要完成剩下的距离,您需要fields_dict()像这样编辑方法:

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
于 2012-08-17T17:21:39.330 回答