【问题标题】:Extending django UserCreationForm扩展 django UserCreationForm
【发布时间】:2018-04-25 15:46:19
【问题描述】:

好吧,我扩展了用户:

class UserProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    sheba = models.DecimalField(max_digits= SHEBA_LENGTH, decimal_places = 0)
    mellicode = models.DecimalField(max_digits=11, decimal_places = 0)

但问题是我们有UserCreationForm 用于用户注册。现在我需要一个新表单来处理添加的字段。我喜欢使用ModelForm 从模型创建表单。现在的问题是UserCreationForm 本身使用ModelFormUser 模型创建字段。 ModelForm 有一个名为 Meta 的内部类,它有一个名为 model 的字段,用于指定应该为想要的字段读取什么模型。我认为应该有办法这样做,因为这是一件很普通的事情。

由于显而易见的原因,我现在无法使用的是:

class SignUpForm(UserCreationForm, ModelForm):
    class Meta(UserCreationForm.Meta):
        model = UserProfile
        fields = ['user','mellicode', 
        'birthdate','residentialaddress','postalcode','sheba','idpic'] 

【问题讨论】:

标签: django forms customization


【解决方案1】:

根据这篇聪明的 guy 的文章,您可以使用以下模型扩展使您的新 UserProfile 模型在创建新用户实例或更新现有实例时自动创建/更新:

class UserProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    sheba = models.DecimalField(max_digits= SHEBA_LENGTH, decimal_places = 0)
    mellicode = models.DecimalField(max_digits=11, decimal_places = 0)

    @receiver(post_save, sender=User)
    def create_user_profile(sender, instance, created, **kwargs):
        if created:
            UserProfile.objects.create(user=instance)

    @receiver(post_save, sender=User)
    def save_user_profile(sender, instance, **kwargs):
        instance.user_profile.save()

因为 Django 允许您在视图中一次处理两个表单,所以您可以使用以下方法解决您的问题:

class UserForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ('first_name', 'last_name', 'email')

class UserProfileForm(forms.ModelForm):
    class Meta:
        model = UserProfile
        fields = ('sheba', 'mellicode')

然后在你的views.py中:

@login_required
@transaction.atomic
def create_user_profile(request):
    if request.method == 'POST':
         user_form = UserForm(request.POST, instance=request.user)
         user_profile_form = UserProfileForm(request.POST, instance=request.user.profile)
         if user_form.is_valid() and user_profile_form.is_valid():
             user_form.save()
             user_profile_form.save()
             messages.success(request, "User successfully created")
         else:
             messages.error(request, "Correct errors")
    else:
        user_form = UserForm(instance=request.user)
        user_profile_form = UserProfileForm(instance=request.user.user_profile)
    return render(request, 'create_profile.html', {
        'user_form': user_form,
        'user_profile_form': user_profile_form
    })

在您的模板中,您将呈现两个表单:

<form method="post">
  {% csrf_token %}
  {{ user_form.as_p }}
  {{ profile_form.as_p }}
  <button type="submit">Save changes</button>
</form>

【讨论】:

  • 谢谢。实际上我已经阅读了那篇文章,但该解决方案对我来说似乎是一种破解或解决方法。我想了想,我认为问题在于 ModelForm 并非设计用于从继承自 ModelForm 的另一个表单继承的表单。
猜你喜欢
  • 2018-03-01
  • 2018-04-08
  • 2013-04-18
  • 2018-07-23
  • 1970-01-01
  • 1970-01-01
  • 2020-06-29
  • 1970-01-01
  • 2012-06-13
相关资源
最近更新 更多