【问题标题】:When subclassing a model field, __init__'s arguments are not processed子类化模型字段时,不处理 __init__ 的参数
【发布时间】:2012-04-25 00:06:03
【问题描述】:

我有一个 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,但生成表单上的标签将是“图像”,即使我使用blank=True,尝试指定空值也会引发错误

【问题讨论】:

    标签: django django-models


    【解决方案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,否则即使表单接受空值,数据库也会拒绝它。另外请注意,在运行syncdb 之后修改null 的值需要进行数据库迁移。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-13
      • 2012-04-27
      • 1970-01-01
      • 2010-12-06
      • 2011-12-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多