1

我正在尝试编辑django.contrib.auth.forms.UserChangeForm. 基本上,auth_user 的用户编辑页面。

https://github.com/django/django/blob/master/django/contrib/auth/forms.py

根据源代码,表单没有save()方法,所以它应该继承自forms.ModelForm对吗?

有关完整代码,请参见此处

class MyUserAdminForm(forms.ModelForm):
    class Meta:
        model = User

    def __init__(self, *args, **kwargs):
        super(MyUserAdminForm, self).__init__(*args, **kwargs)
        instance = getattr(self, 'instance', None)
        if instance and instance.id: # username and user id
            ... the rest of the __init__ is setting readonly fields

    .... some clean methods .....

    def save(self, *args, **kwargs):
        kwargs['commit'] = True
        user = super(MyUserAdminForm, self).save(*args, **kwargs)
        print user.username
        print 'done'
        return user

当我点击保存时,它说'UserForm' object has no attribute 'save_m2m'。我已经google了很多,并尝试使用add()但没有用。是什么导致了这种行为?

问题是:这两个print语句都被打印出来了。但该值从未保存到数据库中。我以为第二行已经保存了一次。

谢谢

4

1 回答 1

4

删除kwargs['commit'] = True线,看看会发生什么。

Django Admin 将在这里调用,它与when isform.save_m2m()挂钩。无条件覆盖 of会破坏of从而引发错误。实际受影响的逻辑在这里formcommitFalsekwargs['commit'] = Truesetattrsave_m2m()formno attribute

def save_form(self, request, form, change):
     """
     Given a ModelForm return an unsaved instance. ``change`` is True if
     the object is being changed, and False if it's being added.
     """
     return form.save(commit=False)

您会发现您的版本无条件form.save()覆盖commit=Falsecommit=True因此 Django Admin 无法继续,因为它认为form.save(commit=False)已被调用,因此form.save_m2m()需要调用。

参考文档

当您的模型与另一个模型具有多对多关系时,会看到使用 commit=False 的另一个副作用。如果您的模型具有多对多关系,并且您在保存表单时指定 commit=False,则 Django 无法立即保存多对多关系的表单数据。这是因为在实例存在于数据库中之前,无法为实例保存多对多数据。

为了解决这个问题,每次您使用 commit=False 保存表单时,Django 都会向您的 ModelForm 子类添加一个 save_m2m() 方法。手动保存表单生成的实例后,可以调用 save_m2m() 来保存多对多表单数据。

于 2012-07-09T09:35:40.747 回答