在模型表单“用户"和“配置文件"中订购字段,并使用表单模板 [英] Order fields in model forms User and Profile and use form template

查看:76
本文介绍了在模型表单“用户"和“配置文件"中订购字段,并使用表单模板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发布了此问题,但我无法获得提供的解决方案.我没有进行编辑,而是发布了一个新代码,其中包含经过修改的代码,该代码使用了不同的方法(具有两种模型形式)

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_profile 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()Usernew_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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆