在模型表单“用户"和“配置文件"中订购字段,并使用表单模板 [英] Order fields in model forms User and Profile and use form template
问题描述
我发布了此问题,但我无法获得提供的解决方案.我没有进行编辑,而是发布了一个新代码,其中包含经过修改的代码,该代码使用了不同的方法(具有两种模型形式)
I posted this question but I couldn't get the solutions provided to work. Instead of editing, I'm posting a new one with the modified code which uses a different approach (with two model forms)
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
location = models.CharField(max_length=30, blank=True)
birth_date = models.DateField(null=True, blank=True)
def __str__(self):
return self.user.username
def create_profile(sender, **kwargs):
user = kwargs["instance"]
if kwargs["created"]:
user_profile= Profile(user=user)
user_profile.save()
post_save.connect(create_profile, sender=User)
forms.py
from django_superform import FormField, SuperForm
class SignUpForm(UserCreationForm):
password1 = forms.CharField(label=("Password"), widget=forms.PasswordInput)
password2 = forms.CharField(label=("Confirm password"), widget=forms.PasswordInput)
class Meta:
model = User
fields = ('username', 'first_name', 'last_name', 'email')
labels = {
'username': ('Capser name'),
}
class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = ('location', 'birth_date')
class SuperProfile(SuperForm):
signupform = FormField(SignUpForm)
profileform = FormField(ProfileForm)
看到我正在使用 Django-superform 包装.原因是我在html模板中使用了表单模板,如模板部分后面所述.
See that I'm using the Superform from Django-superform package. The reason for that is that I'm uing a form template in my html template as explained later in the template section.
<form class="form-horizontal" action="" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<h1>Create a capser account</h1>
<table border="1">
{{ userform.as_table }}
{{ profileform.as_table }}
</table>
{% include 'home/form-template.html' %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-success">Create account</button>
</div>
</div>
</form>
表单模板:form-template.html
{% if messages %}
<ul>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% for field in form %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<span class="text-danger small">{{ field.errors }}</span>
</div>
<label class="control-label col-sm-2">{{ field.label_tag }}</label>
<div class="col-sm-10">{{ field }}</div>
<div class="col-sm-offset-2 col-sm-10">
<span class="text-danger small">{{ field.help_text }}</span>
</div>
</div>
{% endfor %}
和采用新方法的views.py(从两种模型形式导入字段
and the views.py with the new approach (importing fields from the two model forms
class UserFormView(View):
Userform_class = SignUpForm
Profileform_class = ProfileForm
template_name = 'home/registration_form.html'
#display a blank form
def get(self, request):
userform = self.Userform_class(None)
profileform=self.Profileform_class(None)
return render (request, self.template_name, {'userform': userform, 'profileform': profileform})
#process form data
def post(self, request):
userform = self.Userform_class(request.POST)
profileform = self.Profileform_class(request.POST)
if userform.is_valid() and profileform.is_valid():
user = userform.save(commit=False)
#user.refresh_from_db() # load the profile instance created by the signal
password = userform.cleaned_data['password1']
user.set_password(password)
username = userform.cleaned_data['username']
first_name=userform.cleaned_data['first_name']
last_name=userform.cleaned_data['last_name']
email = userform.cleaned_data['email']
user.save()
new_profile = user_profile.objects.get(user = request.user)
new_profile.objects.create(
user=user,
location=profileform.cleaned_data.get('location'),
birth_date=profileform.cleaned_data.get('birth_date'))
new_profile.save()
#return user objects if credentials are correct
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
return redirect('home:home')
return render (request, self.template_name, {'userform': userform, 'profileform':profileform})
现在,当我提交表单时,出现以下错误:name 'user_profile' is not defined
Now when I submit my form, I get the following error : name 'user_profile' is not defined
我认为user_profil
e是在我的model.py
文件末尾创建的实例.
因此,如果这样无法正常工作,该如何在视图中调用我的Profile模型的实例?
I thought that the user_profil
e was the instance created at the end of my model.py
file.
So if this doesn't work like so, how do I call the instance of my Profile model in the view ?
我已经尝试了很多解决方案,但到目前为止都没有奏效.
I've tried a lot of solutions and none worked so far.
此外,我最初想使用表单模板以便在html页面上显示表单,但是现在我使用两种模型表单userform和profileform,我想知道如何使用表单模板(效果不佳).
Also, I initially wanted to use my form-template in order to display my form on the html page, but now that I use two model forms userform and profileform, I wonder on how to use my form template (I tried with Superform without success).
推荐答案
该错误说明了它本身,未定义user_profile
.
您认为部分代码不正确.
您应该处理Django用户模型,并在创建实例后,调用模型Profile
,该模型由OneToOneField
链接到your_app.models
The error says it itself, user_profile
is not defined.
A part of your code is not correct in your views.
You should deal with Django User Model, and after creating the instance, call your model Profile
which is linked by OneToOneField
to User from your your_app.models
from your_app.models import Profile
''' codes here '''
username = userform.cleaned_data['username']
first_name=userform.cleaned_data['first_name']
last_name=userform.cleaned_data['last_name']
email = userform.cleaned_data['email']
user.last_name = last_name
user.first_name = first_name
user.username = username
user.email = email
user.save()
new_profile = Profile.objects.create(
user=user,
location=profileform.cleaned_data.get('location'),
birth_date=profileform.cleaned_data.get('birth_date')
)
new_profile.save()
该问题唯一约束失败:home_profile.user_id 是因为通过执行new_profile.save()
调用了信号post_save
.调用它时,它会创建另一个具有相同user
的配置文件,而当您调用具有OneToOneField()
和User
的new_profile.save()
时,user
已链接到该配置文件.所以只需删除信号
That issue UNIQUE constraint failed: home_profile.user_id is because of the signal post_save
is called by doing new_profile.save()
. When it's called, it creates another profile with the same user
, whereas user
is already linked to the Profile when you had called new_profile.save()
which has an OneToOneField()
with User
. So just remove the signal
这篇关于在模型表单“用户"和“配置文件"中订购字段,并使用表单模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!