在 Django 中使用 inlineformset_factory 时将模型用户设置为当前用户
Setting model user to current user when using inlineformset_factory in Django
我遇到了我花了几个小时试图克服的障碍,我希望得到一些指导。
我有两个模型:Listings 和 Addresses,结构如下:
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对象必须有'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 class 中使用 "exclude = ['user']" 而不是 "fields = ['user']",但结果是创建了一个新地址,但没有创建一个列表来配合它。所以我得到的只是一个新地址,没有列表。
我做错了什么?我将非常感谢解决这个问题,因为很长一段时间以来我一直在用头撞墙!
在这种情况下,我根本不会使用表单集。如果您需要收集用户信息以创建新列表,请使用单个 ListingForm
和 AddressForm
,保存新地址,然后使用 commit=False
保存 ListingForm
,分配用户和地址,然后保存实例。
@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
我遇到了我花了几个小时试图克服的障碍,我希望得到一些指导。
我有两个模型:Listings 和 Addresses,结构如下:
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对象必须有'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 class 中使用 "exclude = ['user']" 而不是 "fields = ['user']",但结果是创建了一个新地址,但没有创建一个列表来配合它。所以我得到的只是一个新地址,没有列表。
我做错了什么?我将非常感谢解决这个问题,因为很长一段时间以来我一直在用头撞墙!
在这种情况下,我根本不会使用表单集。如果您需要收集用户信息以创建新列表,请使用单个 ListingForm
和 AddressForm
,保存新地址,然后使用 commit=False
保存 ListingForm
,分配用户和地址,然后保存实例。
@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