将一个字段和一个方法推入 mixin 破坏了程序

Pushing a field and a method to mixin ruined the program

Django==1.11.4

这个模型运行良好:

class File(CommonUrlMethodsMixin,
           ItemIsMainMixin,
           models.Model):

    item = models.ForeignKey(Item, on_delete=models.PROTECT)

    user_file = models.FileField(blank=False,
                                 max_length=255,
                                 upload_to=get_file_path,
                                 verbose_name=_("file"))

    def __str__(self):
        if self.user_file.name:
            str_repr = "{}:{}".format(str(self.id), self.user_file.name)
        else:
            str_repr = str(self.id)
        return str_repr

但后来我想添加另一个也有 FileField 的模型。新模型看起来与这个非常相似。唯一的区别是外键。

我喜欢这个:

class GeneralFileMixin():
    user_file = models.FileField(blank=False,
                                 max_length=255,
                                 upload_to=get_file_path,
                                 verbose_name=_("file"))

    def __str__(self):
        if self.user_file.name:
            str_repr = "{}:{}".format(str(self.id), self.user_file.name)
        else:
            str_repr = str(self.id)
        return str_repr    


class File(CommonUrlMethodsMixin,
           ItemIsMainMixin,
           GeneralFileMixin,
           models.Model):

    item = models.ForeignKey(Item, on_delete=models.PROTECT)   

我进行了迁移。

forms.py

class FileForm(ModelForm):
    class Meta:
        model = File
        exclude = []
        widgets = {
            'item': forms.HiddenInput()
        }

views.py

class FileCreate(LoginRequiredMixin,
                 CreateView):
    model = File
    form_class = FileForm

但是现在 FileCreate 不显示文件的输入字段。

好了,迁移就到这里:

class Migration(migrations.Migration):

    dependencies = [
        ('files', '0004_auto_20170831_0917'),
    ]

    operations = [
        migrations.RemoveField(
            model_name='file',
            name='user_file',
        ),
    ]

嗯,真的去掉了user_file。但是为什么它没有考虑到 mixin 中的 user_file?

好吧,你能帮我踢一下吗?

你的新 mixin 应该继承 models 并且需要添加 abstarct=True

class GeneralFileMixin(models.Model):
    #                 ^^^^^^^^^^^^
    user_file = models.FileField(blank=False,
                                 max_length=255,
                                 upload_to=get_file_path,
                                 verbose_name=_("file"))

    class Meta:
        abstract = True
    #   ^^^^^^^^^^^^^^
    def __str__(self):
        if self.user_file.name:
            str_repr = "{}:{}".format(str(self.id), self.user_file.name)
        else:
            str_repr = str(self.id)
        return str_repr