2

我有一些带有用户字段的模型。

为此,我想创建一个表单 mixin 来添加self.user实例(在视图中提供给表单)。可能吗 ?

这是示例

class UserFormMixin(object):
    """Removes user instance from kwargs and adding it to object"""
    def __init__(self, *args, **kwargs):
        super(UserFormMixin, self).__init__(*args, **kwargs)
        self.user = kwargs.pop('user')

    def save(self, **kwargs):
        obj = super(UserFormMixin, self).save(commit=False)
        obj.user = self.user
        if kwargs['commit']:
            return obj.save()
        else:
            return obj

我想达到的目标:

class SomeFormWithUserField(UserFormMixin, ModelForm):
    class Meta:
        model = SomeModelWithUserField
        fields = ['fields without user']

    def save(self, **kwargs):
        data = super(SomeFormWithUserField, sefl).save(commit=False)
        #data already with user prepended
        #do some other stuff with data
        if kwargs['commit']:
            return data.save()
        else
            return data

class SomeOtherFormWithUser(UserFormMixin, ModelForm):
    class Meta:
        model = SomeOtherModel
        fields = ['some fields without user']

# no need to save here.. standard model form with user prepended on save()

问题是 UserFormMixin 不知道模型实例?还是我在这里错了?我遇到了一些问题..比如'commit' kwargs key error..或者对象没有保存..

4

2 回答 2

6

你很接近,你只是有一些逻辑错误。首先,为了覆盖ModelForm方法,你的 mixin 需要继承自ModelForm.

class UserFormMixin(forms.ModelForm):
    ...

然后,从它继承的任何形式都只是继承UserFormMixin,而不是ModelForm

class SomeOtherFormWithUser(UserFormMixin):
    ...

其次,您的__init__方法覆盖不正确。您需要接受传入其中的任何和所有 args 和 kwargs。

def __init__(self, *args, **kwargs):
    ...

最后,不要save在子类中再次覆盖该方法。我想这在技术上不会伤害任何东西,但是如果你要重复代码,继承又有什么意义呢?If不可为空,您始终可以在将其添加到模型之前user添加一个 if 块来检查是否。self.user is not None当然,如果它不可为空,那么无论如何user您的模型都不会保存。self.user

于 2012-06-13T14:49:23.597 回答
1

这个似乎工作正常。谢谢克里斯!如果这可以更好地编码,请告诉我。

class UserFormMixin(forms.ModelForm):
    """Removes user instance from kwargs and adding it to object"""
    def __init__(self, *args, **kwargs):
        super(UserFormMixin, self).__init__(*args, **kwargs)
        self.user = kwargs.pop('user')

    def save(self, commit=True):
        obj = super(UserFormMixin, self).save(commit=False)
        obj.user = self.user
        if commit:
            return obj.save()
        else:
            return obj


class SomeFormWithUserField(UserFormMixin):
    class Meta:
        model = SomeModelWithUserField
        fields = ['fields without user']

    def save(self, **kwargs):
        data = super(SomeFormWithUserField, sefl).save(commit=False)
        #data already with user prepended
        #do some other stuff with data
        # self.send_mail() f.e.
        return data.save()

class SomeOtherFormWithUser(UserFormMixin):
    class Meta:
        model = SomeOtherModel
        fields = ['some fields without user']
# this will work too
于 2012-06-13T17:09:09.873 回答