元类与 Django 中的 modelformset_factory 冲突

Posted

技术标签:

【中文标题】元类与 Django 中的 modelformset_factory 冲突【英文标题】:metaclass conflict with modelformset_factory in Django 【发布时间】:2011-12-18 14:15:06 【问题描述】:

我正在使用 Django 模型继承来创建两个模型 - WorkAttachmentPictureWorkAttachmentAudio

class WorkAttachment(models.Model):
    """ Abstract class that holds all fields that are required in each attachment """
    work            = models.ForeignKey(Work)
    added           = models.DateTimeField(default=datetime.datetime.now)
    views           = models.IntegerField(default=0)

    class Meta:
        abstract = True


class WorkAttachmentFileBased(WorkAttachment):
    """ Another base class, but for file based attachments """
    description     = models.CharField(max_length=500, blank=True)
    size            = models.IntegerField(verbose_name=_('size in bytes'))

    class Meta:
        abstract = True


class WorkAttachmentPicture(WorkAttachmentFileBased):
    """ Picture attached to work """
    image           = models.ImageField(upload_to='works/images', width_field='width', height_field='height')
    width           = models.IntegerField()
    height          = models.IntegerField()

class WorkAttachmentAudio(WorkAttachmentFileBased):
    """ Audio file attached to work """
    file            = models.FileField(upload_to='works/audio')

一个作品可以有多个音频和视频附件,所以我使用modelformset_factory来创建表单:

class ImageAttachmentForm(forms.ModelForm):
    """ Image attached to work """
    image = forms.FileField(
        label=_('File'),
        help_text=_('JPEG, GIF or PNG image.')
    )
    description = forms.CharField(
        widget=forms.Textarea(),
        label=_('File description'),
        help_text=_('Max. 500 symbols.'),
        max_length=500
    )

    class Meta:
        model = WorkAttachmentPicture
        fields = ['image', 'description']

ImageAttachmentFormSet = modelformset_factory(WorkAttachmentPicture, form=ImageAttachmentForm)


class AudioAttachmentForm(forms.Form):
    """ Audio file attached to work """
    file = forms.FileField(
        label=_('File'),
        help_text=_('MP3 file.')
    )
    description = forms.CharField(
        widget=forms.Textarea(),
        label=_('File description'),
        help_text=_('Max. 500 symbols.'),
        max_length=500
    )

    class Meta:
        model = WorkAttachmentAudio
        fields = ['file', 'description']

AudioAttachmentFormSet = modelformset_factory(WorkAttachmentAudio, form=AudioAttachmentForm)

对我来说一切似乎都是正确的,但在项目启动时我得到了错误:

metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases

如果我只创建一个表单集(例如ImageAttachmentFormSet),一切正常。但是当我添加另一个时,会出现错误。我该如何解决这个问题,以使用带有继承模型的模型集?

【问题讨论】:

它是单独与他们每个人一起工作,还是只是 AudioAttachmentFrom 坏了? @Autopulated 你是对的,它是 AudioAttachmentFrom。看看下面我自己的答案。 【参考方案1】:

解决了。如果你仔细看

# this has forms.ModelForm
class ImageAttachmentForm(forms.ModelForm):
# this has forms.Form
class AudioAttachmentForm(forms.Form):

我已将 forms.Form 更改为 forms.ModelForm,现在一切正常 - 这是一个简单的复制/粘贴错误。

【讨论】:

以上是关于元类与 Django 中的 modelformset_factory 冲突的主要内容,如果未能解决你的问题,请参考以下文章

Python 子类跟踪 - 元类与内置

模型元类与模型形式元类有何不同?

Python 元类与类装饰器

将元类与多重继承结合使用的 TypeErrors

Groovy 元类与 Java 8 的互操作性

Python入门自学进阶——6--类与对象-成员修饰符特殊成员及元类