我遇到了一个障碍,我花了好几个小时试图克服,我会很感激一些指导。
我有两个模型:列表和地址,具有以下结构:
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']”,但这样做的结果是创建了一个新地址而没有创建一个列表来使用它。所以我得到的只是一个新地址,没有列表。
我做错了什么?我会非常感激解决这个问题,因为我一直在墙上撞了很长时间!
答案 0 :(得分:1)
在这种情况下,我根本不会使用formset。如果您需要收集用户信息以创建新商家信息,请使用单个ListingForm
和AddressForm
,保存新地址,然后将ListingForm
与commit=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