ModelForm用户Mixin

Rob*_*ert 1 forms django modelform

我有一些用户字段的模型.

为此,我想创建一个表单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
Run Code Online (Sandbox Code Playgroud)

我想要实现的目标:

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()
Run Code Online (Sandbox Code Playgroud)

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

Chr*_*att 6

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

class UserFormMixin(forms.ModelForm):
    ...
Run Code Online (Sandbox Code Playgroud)

然后,从它继承的任何表单都只是继承UserFormMixin,而不是ModelForm.

class SomeOtherFormWithUser(UserFormMixin):
    ...
Run Code Online (Sandbox Code Playgroud)

其次,您的__init__方法覆盖不正确.你需要接受传递给它的任何和所有的args和kwargs.

def __init__(self, *args, **kwargs):
    ...
Run Code Online (Sandbox Code Playgroud)

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