在ModelForms中获取用户OneToOneField字段 [英] Get user OneToOneField fields in ModelForms

查看:47
本文介绍了在ModelForms中获取用户OneToOneField字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用 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.

      内联表单集是模型表单集之上的一个小的抽象层.这些简化了通过外键处理相关对象的情况.

      Inline formsets is a small abstraction layer on top of model formsets. These simplify the case of working with related objects via a foreign key.

      您可以在此处找到好示例.

      或者,如果要避免使用内联表单集,并在单个< form> 标记下同时使用 ProfileForm AddressForm 就像您在模板中所做的一样,您可以像那样进行操作.

      Alternatively, if you want to avoid inline formsets and use both ProfileForm and AddressForm 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字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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