使ModelForm字段的空白属性动态化

时间:2014-01-28 16:46:52

标签: django

我有一个用户模型:

class User(models.Model):
    email = models.CharField(
        max_length=254,
        unique=True,
    )

    password = models.CharField(
        max_length=160,
        blank=True,
    )

我希望空白属性仅在编辑现有用户时为true,在添加新用户时为false。

我正在尝试类似的事情:

class UserForm(ModelForm):
    class Meta:
        model = User
        widgets = {
            'password': PasswordInput(),
        }

class UserAdmin(admin.ModelAdmin):
    form = UserForm

    def save_model(self, request, obj, form, change):
        # Only change password when not blank
        if request.POST['password'] != '':
            obj.password = encrypt(request.POST['password'])
        else:
            if obj.pk is not None:
                obj = obj.__class__._default_manager.get(pk=obj.pk)
            else:
                self.form.Meta.model.password.blank = False
        obj.save()

我收到此错误:

type object 'User' has no attribute 'password'

所以这条线不起作用:

self.form.Meta.model.password.blank = False

是否可以根据添加新用户还是编辑现有用户将空白值从true切换为false,反之亦然?

2 个答案:

答案 0 :(得分:0)

这不是实现您的要求的正确方法。

如果password字段可以包含空值,则应在模型中设置blank=True,然后在表单中实现验证逻辑。

答案 1 :(得分:0)

把它想象成我自己。这很好用:

class UserForm(ModelForm):
    class Meta:
        model = User
        widgets = {
            'password': PasswordInput(),
        }

    def clean(self):
        cleaned_data = super(UserForm, self).clean()

        if self.instance.pk is None and self.cleaned_data['password'] == '':
            self._update_errors(ValidationError({
                'password': [
                    'Required when creating a new user',
                ]
            }))

        return cleaned_data

class UserAdmin(admin.ModelAdmin):
    form = UserForm

    def save_model(self, request, obj, form, change):
        # Only change password when not blank
        if request.POST['password'] != '':
            obj.password = encrypt(request.POST['password'])
        elif obj.pk is not None:
            obj = obj.__class__._default_manager.get(pk=obj.pk)
        obj.save()