在Django中使用inlineformset_factory时,将模型用户设置为当前用户 [英] Setting model user to current user when using inlineformset_factory in Django

查看:194
本文介绍了在Django中使用inlineformset_factory时,将模型用户设置为当前用户的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经打了几个小时试图克服的路障,我会感谢一些指导。

I've hit a roadblock that I've spent hours trying to overcome, and I would appreciate some guidance.

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

I have two models: Listings and Addresses, with the following structure:

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对象,但是Listings对象必须具有与当前登录用户的id相同的'user'外键。

I'm trying to create a form which will add a new listing, however the only information to be entered are the fields in the Addresses model. When the form is submitted, I need a new Listings object and a new Addresses object to be created, but the Listings object must have the 'user' foreign key equal to the id of the current logged-in user.

这是视图:

@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'],但是这样做的结果是创建一个新的地址而不创建一个列表。所以我得到的是一个新的地址,没有列出。

In its current state, I get a form containing all the address fields, plus a drop-down user field. When the form is submitted, it creates a new listing with two foreign keys: one for the chosen user, and another for the new address that has just been created. This end result is what I want. HOWEVER, I don't want there to be a drop-down user field in the form - I need the user to be set to the current user. I tried using "exclude = ['user']" in the ListingForm class instead of "fields = ['user']", but this had the result of creating a new address without creating a listing to go with it. So all I got was a new address, and no listing.

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

What am I doing wrong? I would be so grateful for a solution to this, as I've been banging my head against a wall for a very long time!

推荐答案

在这种情况下,我根本不会使用表单。如果您需要收集用户信息来创建新的列表,请使用单个 ListingForm AddressForm ,保存新地址,然后将 ListingForm commit = False 保存,为其分配用户和地址,然后保存实例。

In this case I wouldn't use a formset at all. If you need to collect user information to create the new listing, use a single ListingForm and AddressForm, save the new address, and then save the ListingForm with commit=False, assign the user and address to it, and then save the instance.

@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
    })

如果您在列表之间有多对多关系,则需要明确保存保存实例,如下所述:
https://docs.djangoproject.com/en/1.10/topics/forms/modelforms/#the-save-method

If you ever have a many-to-many relationship on Listings you'll need to explicitly save those after saving the instance, as discussed here: https://docs.djangoproject.com/en/1.10/topics/forms/modelforms/#the-save-method

这篇关于在Django中使用inlineformset_factory时,将模型用户设置为当前用户的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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