【问题标题】:Order fields in model forms User and Profile and use form template模型表单用户和配置文件中的订单字段并使用表单模板
【发布时间】:2018-04-18 00:56:31
【问题描述】:

我发布了this question,但我无法让提供的解决方案发挥作用。我没有进行编辑,而是发布了一个带有修改后代码的新代码,该代码使用了不同的方法(具有两种模型形式)

models.py

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 包的 Superform。原因是我在我的 html 模板中使用了表单模板,稍后在模板部分中进行了说明。

模板

html页面模板:registration_form.html

<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(从两个模型表单中导入字段

views.py

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

我认为user_profile 是在我的model.py 文件末尾创建的实例。 因此,如果这不起作用,我该如何在视图中调用我的 Profile 模型的实例?

我已经尝试了很多解决方案,但到目前为止都没有奏效。

另外,我最初想使用我的表单模板来在 html 页面上显示我的表单,但现在我使用了两个模型表单 userform 和 profileform,我想知道如何使用我的表单模板(我试过超形式没有成功)。

【问题讨论】:

    标签: django forms


    【解决方案1】:

    错误说明了它本身,user_profile 未定义。 您的部分代码在您的视图中不正确。 您应该处理 Django 用户模型,并在创建实例后,调用您的模型 Profile,该模型通过 OneToOneField 链接到您的 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()
    

    那个问题UNIQUE constraint failed: home_profile.user_id是因为信号post_savenew_profile.save()调用了。当它被调用时,它会创建另一个具有相同user 的配置文件,而当您调用new_profile.save() 时,user 已经链接到具有OneToOneField()User 的配置文件。所以只要去掉信号

    【讨论】:

    • 显然,我错过了这一点。现在我收到此错误UNIQUE constraint failed: home_profile.user_id,我认为是由于Profile.objects.create 之后的user=user 行,但是当我删除它时,我收到另一个错误:NOT NULL constraint failed: home_profile.user_id 再次卡住。
    • 我已经编辑了我的答案,在我之前写的下面,你会发现为什么会出现这些错误。
    • 我标记为已回答。终于让它工作了。如果我可以对您的回答投 3 分,我会这样做。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-02
    • 1970-01-01
    • 2020-07-03
    • 2019-04-27
    • 2013-08-27
    • 2021-02-20
    相关资源
    最近更新 更多