当用户模型具有OneToOneField连接到ModelForms django中的另一个模型时,更改用户模型的值 [英] Change Values of User Model while it has OneToOneField Connection to another model in ModelForms django
问题描述
我在Django ModelForms中遇到问题,这是其中一个
i have problems with Django ModelForms and here is one of them
我想在Django中为User Model提供一些额外的字段,因此在models.py中创建了CustomeUser Model
i wanna have some extra fields for User Model in Django and so made an CustomeUser Model in models.py
class CustomeUser(models.Model):
user = models.OneToOneField(User)
City = models.ForeignKey(City, on_delete=models.CASCADE, blank=True, null=True)
Gender = models.ForeignKey(Gender, null=True, blank=True)
DateOfBirth = models.DateField(null=True, blank=True)
ProfilePicture = models.ImageField(verbose_name="Profile Picture", upload_to=user_directory_path, null=True, blank=True, max_length=255)
Address = models.CharField(max_length=255, blank=True, null=True)
def __str__(self):
return str(self.user)
现在我想用ModelForm制作EditProfileForm,这是我所做的:
and now i wanna make EditProfileForm with ModelForm, here is what i did:
class EditProfileForm(forms.ModelForm):
firstname = forms.CharField(max_length=35,required=False)
lastname = forms.CharField(max_length=35, required=False)
cityid = forms.ModelChoiceField(queryset=City.objects.values('id').all(), required=False)
genderid = forms.ModelChoiceField(queryset=Gender.objects.values('id').all(), required=False)
dateofbirth = forms.DateField(required=False)
profilepicture = forms.ImageField(required=False, max_length=255)
address = forms.CharField(max_length=255, required=False)
class Meta:
model = CustomeUser
fields = ['firstname' ,'lastname' ,'cityid' , 'genderid', 'dateofbirth', 'profilepicture', 'address' ]
我真的不知道如何以最佳方式做到这一点
i really have no idea how to do it in the best way
推荐答案
models.py
models.py
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
bio = models.TextField(max_length=500, blank=True)
location = models.CharField(max_length=30, blank=True)
birth_date = models.DateField(null=True, blank=True)
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
instance.profile.save()
钩住 create_user_profile
和只要发生保存事件,就将User_user_profile
方法保存到User模型。这种信号称为 post_save
。
hooking the create_user_profile
and save_user_profile
methods to the User model, whenever a save event occurs. This kind of signal is called post_save
.
forms.py
class UserForm(forms.ModelForm):
class Meta:
model = User
fields = ('first_name', 'last_name', 'email')
class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = ('bio', 'location', 'birth_date')
views.py
@login_required
@transaction.atomic
def update_profile(request):
if request.method == 'POST':
user_form = UserForm(request.POST, instance=request.user)
profile_form = ProfileForm(request.POST, instance=request.user.profile)
if user_form.is_valid() and profile_form.is_valid():
user_form.save()
profile_form.save()
messages.success(request, _('Your profile was successfully updated!'))
return redirect('settings:profile')
else:
messages.error(request, _('Please correct the error below.'))
else:
user_form = UserForm(instance=request.user)
profile_form = ProfileForm(instance=request.user.profile)
return render(request, 'profiles/profile.html', {
'user_form': user_form,
'profile_form': profile_form
})
profile.html
profile.html
<form method="post">
{% csrf_token %}
{{ user_form.as_p }}
{{ profile_form.as_p }}
<button type="submit">Save changes</button>
</form>
您可以在单个数据库查询中预取相关数据:
you can prefetch related data in a single database query:
users = User.objects.all().select_related('profile')
*您可以更改字段和类名,而不用使用Profile
*You can change fields and class name instead of using Profile
这篇关于当用户模型具有OneToOneField连接到ModelForms django中的另一个模型时,更改用户模型的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!