使用django形式更新onetoone相关模型的字段

时间:2017-11-02 17:30:44

标签: django django-forms

在models.py中:

class UserProfile(models.Model):
    user = AutoOneToOneField(User, on_delete=models.CASCADE)
    avatar = models.ImageField(upload_to='user_avatars/', default = 'user_avatars/default-avatar.jpg')
    male = 'M'
    female = 'F'
    gender_choices = ((male,'Male'), (female,'Female'))
    gender = models.CharField(choices = gender_choices, max_length = 10)
    dateOfBirth = models.DateField(default = datetime.date.today)
    follows = models.ManyToManyField("self", related_name = 'followers', symmetrical=False,\
                                        blank = True)
    favorite_pet = models.ManyToManyField(Pet, blank = True)

    def __str__(self):
        return self.user.username

在forms.py中:

class EditProfileForm(forms.ModelForm):

    first_name = forms.CharField(label='First Name')
    last_name = forms.CharField(label='Last Name')
    email = forms.EmailField()
    gender_choices = (('M', 'Male'), ('F', 'Female'))
    gender = models.CharField(choices=gender_choices, max_length=10)
    dateOfBirth = models.DateField()

    class Meta:
        model = User
        fields = ['first_name', 'last_name', 'email']

我希望允许用户更改自己的genderdateOfBirth。但是,这些字段属于UserProfile类(与User具有一对一的关系),因此,如果我将'gender'和'dateOfBirth'添加到元类中的数组字段,我会得到“未知字段“来自User类的错误。谁能告诉我如何实现我的目标?任何帮助将受到高度赞赏:D

2 个答案:

答案 0 :(得分:0)

让User模型添加一个方法来调用它的相关UserProfile实例并对其进行更新。我通常通过将实例作为变量调用来完成它,但我相信您可以通过保存ForeignKey / ManytoMany等的实例属性直接访问它。

class User(models.Model):
attributes = models.Fields()
user_profile = models.ForeignKey()

def update_profile(self):
    self.user_profile.gender = self.gender
    self.user_profile.DateOfBirth = self.date_of_birth
    self.user_profile.save()

答案 1 :(得分:0)

非常感谢@bubthegreat虽然我仍然对你的回答感到困惑(我的UserProfile模型与User中的默认django.contrib.auth.models有一对一的关系,而不是手工创建的像你的)。

我想出了如何解决我的问题。在views.py

def edit_profile(request):
    user = request.user
    user_form = UserForm(request.POST or None, \
                        initial={'first_name': user.first_name, 'last_name': user.last_name,
                                 'email': user.email}, instance = request.user)
    user_profile_form = ProfileForm(request.POST or None, \
                        initial={'gender': user.userprofile.gender, 'dateOfBirth': user.userprofile.dateOfBirth}, \
                        instance=request.user.userprofile)

    if request.method == 'POST':
        if user_form.is_valid() and user_profile_form.is_valid():
            user.first_name = user_form.cleaned_data['first_name']
            user.last_name = user_form.cleaned_data['last_name']
            user.email = user_form.cleaned_data['email']
            user.userprofile.gender = user_profile_form.cleaned_data['gender']
            user.userprofile.dateOfBirth = user_profile_form.cleaned_data['dateOfBirth']
            user.save()
            user.userprofile.save()
            return HttpResponseRedirect(reverse('pet:current user profile'))
    context = {
        "user_form": user_form,
        "user_profile_form": user_profile_form
    }
    return render(request, "edit_profile.html", context)

forms.py

class UserForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ('first_name', 'last_name', 'email')


class ProfileForm(forms.ModelForm):
    class Meta:
        model = UserProfile
        fields = ('gender', 'dateOfBirth')