Django auth用户的用户更改表单上的super()保存方法

时间:2012-07-09 04:57:19

标签: django django-models django-forms django-admin

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

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

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

完整代码,see here

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'。我用谷歌搜索了一下,并试图使用add()但是没有用。是什么导致了这种行为?

事情是:打印两个print语句。但价值从未保存到数据库中。我以为第二行已经保存了一次。

由于

1 个答案:

答案 0 :(得分:4)

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

Django Admin会调用form.save_m2m(),当formcommit here时,它会挂钩False。无条件覆盖kwargs['commit'] = True会将setattr save_m2m()分解为form,从而引发no attribute错误。实际受影响的逻辑是here

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管理员无法继续,因为它认为form.save(commit=False)被调用,因此{{需要调用1}}。

参考the doc

  

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

     

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