在ModelForms中获取用户OneToOneField字段

时间:2016-07-02 21:21:13

标签: django forms django-models

我已经使用OneToOneField扩展了django用户,因此我可以存储地址等。

SiteUser是使用User扩展OneToOneField的模型。如何在一个User中获取SiteUserModelForm的字段?

以下是目前的相关代码:

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页面我想要表格:

{% 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 %}

3 个答案:

答案 0 :(得分:2)

  • 一种选择是使用inline formsets。使用此功能,您将不需要第二个ModelForm

      

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

    您可以找到good examples here

  • 或者,如果您想避免使用内联表单集并在单个ProfileForm标记下使用AddressForm<form>,就像在模板中一样,您可以执行此操作比如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,
        })
    

答案 1 :(得分:0)

我对表单知之甚少,但我认为在实例化AddressForm时应该使用“initial”参数,如下所示:https://docs.djangoproject.com/es/1.9/topics/forms/modelforms/#providing-initial-values

所以你用SiteUser作为模型创建你的AddressForm类,当你在视图中实例化它时,你就这样做:

AddressForm(initial={'user': request.user})

如果“username”不是User模型的主键,您可以像这样获得主键:

User.objects.get(username=request.user).pk

然后在“initial”参数中给出它。

答案 2 :(得分:0)

型号:

class Company(models.Model):
    name = models.CharField(max_length=150)
    description = models.CharField(max_length=150)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)


class Bike(models.Model):
    to_company = models.OneToOneField(Company, on_delete=models.CASCADE, related_name="bike_company")
    name_bike = models.CharField(max_length=150)
    model = models.CharField(max_length=150)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

form.py

class CompanyForm(ModelForm):
    class Meta:
        model = Company
        fields = ("name", "description" )


class BikeForm(ModelForm):
    name_bike = forms.CharField(required=True)
    model = forms.CharField(required=True)

    class Meta(CompanyForm.Meta):
        model = Company

    @transaction.atomic
    def save(self):
        company = super().save(commit=False)
        company.name = self.cleaned_data.get("name")
        company.description = self.cleaned_data.get("description")
        company.save()
        bike = Bike.objects.create(to_company=company)
        bike.name_bike = self.cleaned_data.get("name_bike")
        bike.model = self.cleaned_data.get("model")
        bike.save()
        return company

关系保持在这一行:

Bike.objects.create(to_company=company)

这是一个不同类型的用户模型的例子

建模用户和类型 https://gist.github.com/josuedjh3/259b4b3b03ab195637fe2db3c701edd6

FormModel the User 和 UserCreationForm

https://gist.github.com/josuedjh3/0c26d989552a82d5b252c5bd3fed1054

相关问题