努力弄清楚如何在我的Django表单中覆盖__init__()
方法以包含数据库中的其他值。我有一组摄影师,我试图将其列为用户的表单选项。之后,用户的摄影师选择(连同其他信息)将作为新模型的实例添加到数据库中。
这是我的另一个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()
来自models.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: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 :(得分: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()
的代码。
答案 1 :(得分:1)
GitHub链接应该是你问题中的第一件事。
django-classifieds
application有一整套动态字段系统(基于Field
和FieldValue
模型),这就是您遇到问题的原因。如果您不完全理解django-classifieds
的这一方面,我建议您将项目建立在其他方面。
在FIELD_CHOICES
的{{1}}中查看django-classified
列表,您无法使用此数据库驱动的字段系统来定义关系 - 因此每个类别没有动态{ {1}}字段!
替代方法是在models.py
模型上添加ForeignKey
字段(您从photographer
重命名的任何特定原因?),因为您似乎已基于你的另一个问题。但是,为了完成剩余的距离,您需要像这样编辑A
方法:
Ad