如何从预先填充对象

时间:2016-03-27 00:25:36

标签: python django django-models django-forms

如何从实例中创建的表单中排除某些字段? 我想允许用户编辑他们的属性,如用户名或电话,但在这种形式下,他们不应该更改他们的密码。

我试过这个:

del user_profile_form.fields['telephone']

但是当我这样做时它会引发CSRF token missing or incorrect.

@login_required
def edit_profile(request):
    user = request.user
    user_form = UserForm(instance=user)
    user_profile_form = UserProfileForm(instance=user.userprofile)

    context = {'user_form': user_form,
               'user_profile_form': user_profile_form}

    return render(request, 'auth/profiles/edit-profile.html', context=context)

FORMS.PY

class UserForm(forms.ModelForm):
    password1 = forms.CharField(widget=forms.PasswordInput())
    password2 = forms.CharField(widget=forms.PasswordInput())

    class Meta:
        model = User
        fields = ('username', 'email', 'password1','password2', 'first_name', 'last_name')

    def clean(self):
        password1 = self.cleaned_data.get('password1')
        password2 = self.cleaned_data.get('password2')

        if password1 and password1 != password2:
            raise forms.ValidationError("Passwords don't match")

        return self.cleaned_data

class UserProfileForm(forms.ModelForm):
    class Meta:
        model = UserProfile
        fields = ('telephone','marital_status','how_do_you_know_about_us')

MODELS.PY

class UserProfile(models.Model):
    user = models.OneToOneField(User,on_delete=models.CASCADE,related_name='userprofile')

    # ATRIBUTY KTORE BUDE MAT KAZDY
    telephone = models.CharField(max_length=40,null=True)

    HOW_DO_YOU_KNOW_ABOUT_US_CHOICES = (
            ('coincidence',u'It was coincidence'),
            ('relative_or_friends','From my relatives or friends'),
            )
    how_do_you_know_about_us = models.CharField(max_length=40, choices=HOW_DO_YOU_KNOW_ABOUT_US_CHOICES, null=True)

    MARITAL_STATUS_CHOICES = (
        ('single','Single'),
        ('married','Married'),
        ('separated','Separated'),
        ('divorced','Divorced'),
        ('widowed','Widowed'),
    )
    marital_status = models.CharField(max_length=40, choices=MARITAL_STATUS_CHOICES, null=True)

    # OD KIAL STE SA O NAS DOZVEDELI
    # A STAV

    def __unicode__(self):
        return '{} {}'.format(self.user.first_name,self.user.last_name)

    def __str__(self):
        return '{} {}'.format(self.user.first_name,self.user.last_name)

新视图

@login_required
def edit_profile(request):
    user = request.user
    if request.method == 'POST':
        user_form = UserForm(request.POST)
        user_profile_form = UserProfileForm(request)
        if user_form.is_valid() and user_profile_form.is_valid():
            user_form.save()
            user_profile_form.save()
            return HttpResponseRedirect('/logged-in')
        else:
            print user_form.errors
            print user_profile_form.errors

    else:
        user_form = UserForm(instance=user)
        user_profile_form = UserProfileForm(instance=user.userprofile)
        temp_user_profile_form = deepcopy(user_profile_form)
        del temp_user_profile_form.fields['password1']
        del temp_user_profile_form.fields['password2']
    context = {'user_form': user_form,
               'user_profile_form': temp_user_profile_form}

    return render(request, 'auth/profiles/edit-profile.html', context=context)

错误

Exception Type: KeyError
Exception Value:    
'password1'

1 个答案:

答案 0 :(得分:1)

您似乎在password1类中引用了password2模型表单中的MetaUserForm。这些应该被删除,因为它们不是用户模型中的字段。因此,在更改后,您的UserForm应为:

class UserForm(forms.ModelForm):
    # These 2 fields are unbound fields...
    password1 = forms.CharField(widget=forms.PasswordInput())
    password2 = forms.CharField(widget=forms.PasswordInput())

    class Meta:
        model = User
        # These fields are your User model's fields
        fields = ('username', 'email', 'first_name', 'last_name')

    def clean(self):
        password1 = self.cleaned_data.get('password1')
        password2 = self.cleaned_data.get('password2')

        if password1 and password1 != password2:
            raise forms.ValidationError("Passwords don't match")

        return self.cleaned_data

您不需要在视图中删除它们。只需在模板中排除它们即可。

此外,如果您愿意,可以在表单的__init__方法中为表单字段隐藏输入。我推荐这种方法。