问题描述
我用 OneToOneField
扩展了django用户,以便我可以存储地址等.
I've extended the django user with a OneToOneField
so I can store address and such.
SiteUser
是使用 OneToOneField
扩展 User
的模型.如何在单个 ModelForm
中获得 User
和 SiteUser
的字段?
SiteUser
is the model which extends User
using a OneToOneField
. How can I get fields of both User
and SiteUser
in a single ModelForm
?
这是到目前为止的相关代码:
Here is the relevant code so far:
class ProfileForm(ModelForm):
class Meta:
model = User
fields = ('username', 'first_name', 'last_name', 'email')
class AddressForm(ModelForm):
pass
有问题的视图:
def edit_profile(request):
username = request.user
user = User.objects.get(username__exact=username)
profileform_class = ProfileForm
if request.method == 'POST':
profileform = profileform_class(data=request.POST, instance=user)
if profileform.is_valid():
profileform.save()
return redirect('profile')
else:
profileform = profileform_class(instance=user)
return render(request, 'edit_profile.html', {
'user': user,
'profileform': profileform,
})
以及两个模型:
class Product(models.Model):
order = models.IntegerField(default=0)
name = models.CharField(max_length=255)
description = models.TextField()
image = models.ImageField(upload_to='product-images', default='default.jpg')
price = models.FloatField()
slug = models.SlugField(unique=True)
class SiteUser(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
address = models.CharField(max_length=255)
post_number = models.CharField(max_length=255, default='')
post_location = models.CharField(max_length=255, default='')
HTML页面我希望使用以下表单:
HTML Page I want the forms on:
{% extends 'base.html' %}
{% block title %}
Rediger {{ product.name }} - {{ block.super }}
{% endblock title %}
{% block content %}
<h1>Rediger "{{ user }}"</h1>
<form role="form" action="" method="post">
{% csrf_token %}
{{ profileform.as_p }}
{{ addressform.as_p }}
<button type="submit">Submit</button>
</form>
{% endblock content %}
推荐答案
-
一个选项是使用内嵌表单集.使用此功能,您将不需要第二个
ModelForm
.One option is to use inline formsets. Using this, you won't be needing a second
ModelForm
.您可以在此处找到好示例.
或者,如果要避免使用内联表单集,并在单个
< form>
标记下同时使用ProfileForm
和AddressForm
就像您在模板中所做的一样,您可以像此那样进行操作.Alternatively, if you want to avoid inline formsets and use both
ProfileForm
andAddressForm
under a single<form>
tag as you have done in your template, you can do it like this.表格:
class ProfileForm(ModelForm): class Meta: model = User fields = ('username', 'first_name', 'last_name', 'email') class AddressForm(ModelForm): class Meta: model = SiteUser exclude = ['user']
观看次数:
def edit_profile(request): username = request.user user = User.objects.get(username__exact=username) profileform_class = ProfileForm addressform_class = AddressForm if request.method == 'POST': profileform = profileform_class(data=request.POST, instance=user) addressform = addressform_class(data=request.POST, instance=user.siteuser) if all((profileform.is_valid(), addressform.is_valid())): user = profileform.save() address = addressform.save(commit=False) address.user = user address.save() return redirect('profile') else: profileform = profileform_class(instance=user) addressform = addressform_class(instance=user.siteuser) return render(request, 'edit_profile.html', { 'user': user, 'profileform': profileform, 'addressform': addressform, })
这篇关于在ModelForms中获取用户OneToOneField字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!