我有一个models.ForeignKey的子类,其唯一目的是使用自定义小部件:
from django.db import models
from .models import Images
class GAEImageField(models.ForeignKey):
def __init__(self, **kwargs):
super(GAEImageField, self).__init__(Images, **kwargs)
def formfield(self, *args, **kwargs):
field = forms.ModelChoiceField(self, widget=ImageUploadWidget, *args, **kwargs)
field.queryset = Images.objects.all()
return field
问题是,当我尝试使用此字段时,忽略__init__
的所有参数。例如,如果我尝试这个模型:
class SomethingWithImage(models.Model):
name = models.CharField('Awesome name', max_length=64)
image = GAEImageField(verbose_name='Awesome image', blank=True)
...尽管事实上我指定了verbose_name,但生成的表单上的标签将是“Image”并且尝试指定空值会引发错误,即使我使用blank = True
答案 0 :(得分:1)
嗯,问题出在你的formfield
方法上。例如,如果您查看默认ForeignKey
中使用的实现,您会看到它调用super
。我推荐这样的东西:
def formfield(self, **kwargs):
defaults = {
'widget': ImageUploadWidget,
}
defaults.update(kwargs)
return super(GAEImageField, self).formfield(**defaults)
问题是,表单字段不会从模型字段中提取任何信息。表单字段可以完全独立于模型使用,它们不必必须由模型字段支持。这意味着所有设置,例如字段是否需要,其标签等必须作为参数传递给它们的构造函数。模型字段负责创建表单字段的适当实例,包括所有设置。 django.db.models.fields.Field.formfield
的默认实现负责处理您通常想要调用父方法的原因。
对于blank
问题,请尝试设置null=True
,否则即使表单接受空值,数据库也会拒绝它。另请注意,在null
运行后修改syncdb
的值需要进行数据库迁移。