在Django中使用inlineformset_factory时将模型用户设置为当前用户

时间:2016-12-22 19:37:10

标签: django django-models django-forms inline-formset

我遇到了一个障碍,我花了好几个小时试图克服,我会很感激一些指导。

我有两个模型:列表和地址,具有以下结构:

class Listings(models.Model):
    created_date = models.DateTimeField(auto_now_add=True)
    pub_date = models.DateTimeField(auto_now_add=True)
    address = models.ForeignKey(Addresses)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    is_active = models.BooleanField(default=1)

class Addresses(models.Model):
    address1 = models.CharField(max_length=100)
    address2 = models.CharField(max_length=100)
    address3 = models.CharField(max_length=100)
    address4 = models.CharField(max_length=100)
    postcode = models.CharField(max_length=8)

我也有这些:

class AddressForm(ModelForm):
    class Meta:
        model = Addresses
        fields = ['address1', 'address2', 'address3', 'address4', 'postcode']

class ListingForm(ModelForm):
    class Meta:
        model = Listings
        fields = ['user']

我正在尝试创建一个将添加新列表的表单,但是要输入的唯一信息是地址模型中的字段。提交表单时,我需要一个新的Listings对象和一个要创建的新Addresses对象,但是对象必须使'user'外键等于当前登录用户的id。

这是观点:

@login_required(login_url='share:login_view',          redirect_field_name='share:addlisting')
def addlisting(request):

    ListingInlineFormSet = inlineformset_factory(Addresses, Listings, form=ListingForm, can_delete=False, extra=1)

    if request.method == 'POST':

        address_form = AddressForm(request.POST)
        if address_form.is_valid():
            new_address = address_form.save()
            listing_formset = ListingInlineFormSet(request.POST, request.FILES, instance=new_address)

            if listing_formset.is_valid():
                listing_formset.save()
                return HttpResponseRedirect(reverse('/listing_added/'))

    else:
        address_form = AddressForm()
        listing_formset = ListingInlineFormSet()

    return render(request, 'share/addlisting.html', {
        "address_form": address_form,
        "listing_formset": listing_formset,
    })

在当前状态下,我得到一个包含所有地址字段的表单,以及一个下拉用户字段。提交表单时,它会创建一个包含两个外键的新列表:一个用于所选用户,另一个用于刚刚创建的新地址。这个结果就是我想要的。但是,我不希望表单中有一个下拉用户字段 - 我需要将用户设置为当前用户。我尝试在ListingForm类中使用“exclude = ['user']”而不是“fields = ['user']”,但这样做的结果是创建了一个新地址而没有创建一个列表来使用它。所以我得到的只是一个新地址,没有列表。

我做错了什么?我会非常感激解决这个问题,因为我一直在墙上撞了很长时间!

1 个答案:

答案 0 :(得分:1)

在这种情况下,我根本不会使用formset。如果您需要收集用户信息以创建新商家信息,请使用单个ListingFormAddressForm,保存新地址,然后将ListingFormcommit=False一起保存,分配用户和地址,然后保存实例。

@login_required(login_url='share:login_view', redirect_field_name='share:addlisting')
def addlisting(request):
    if request.method == 'POST':
        address_form = AddressForm(request.POST, prefix="address")
        listing_form = ListingForm(request.POST, prefix="listing")
        if address_form.is_valid() and listing_form.is_valid():
            new_address = address_form.save()
            new_listing = listing_form.save(commit=False)
            new_listing.address = new_address
            new_listing.user = request.user
            new_listing.save()
            return HttpResponseRedirect(reverse('/listing_added/'))
    else:
        address_form = AddressForm(prefix="address")
        listing_form = ListingForm(prefix="listing")
    return render(request, 'share/addlisting.html', {
        "address_form": address_form,
        "listing_form": listing_form
    })

如果您在Listings上拥有多对多关系,则需要在保存实例后明确保存这些关系,如下所述: https://docs.djangoproject.com/en/1.10/topics/forms/modelforms/#the-save-method