【发布时间】:2020-02-26 09:37:52
【问题描述】:
我正在做这个项目,我可以在模板中添加两个或多个表单。我能够在模板中获得这两个表格,但是当我提交表格时,我获得了rentalproperty 模型而不是合同模型的对象。我创建了两种不同的解决方案,但两者都没有解决问题。
下面的第一个解决方案在详细视图中多次显示两个对象,但我想要的是只显示两个模型对象一次。第二种解决方案显示一次rentalproperty 对象,但多次显示contract 对象。有人能指出我正确的方向吗?谢谢。
第一个解决方案: 视图.py
class DetailView(generic.DetailView):
model = RentalProperty
template_name = 'rental/detail.html'
context_object_name = 'property'
def new_rental(request, pk):
if request.method == 'POST':
rental_form = NewRentalPropertyForm(request.POST, request.FILES, prefix = "rentals")
contract_form = NewContractForm(request.POST, prefix = "contracts")
if rental_form.is_valid() and contract_form.is_valid():
print ("all validation passed")
rentalproperty = rental_form.save()
contract_form.cleaned_data["rentalproperty"] = rentalproperty
print(contract_form)
contract = contract_form.save(commit=False)
contract.rentalproperty = rentalproperty
contract = contract_form.save()
return HttpResponseRedirect(reverse("home"))
else:
messages.error(request, "Error")
contract = Contract.objects.get(pk=pk)
else:
rental_form = NewRentalPropertyForm(prefix = "rentals")
contract_form = NewContractForm(prefix = "contracts")
contract = Contract.objects.get(pk=pk)
return render(request, 'rental/new_rental.html', {
#'rentalproperty': rentalproperty,
'rental_form': rental_form,
'contract_form': contract_form,
'contract': contract,
})
detail.html
<h1>This is the detail view</h1>
<h3>From landlord</h3>
<p>Landlord: {{property.created_by}}</p>
<p>address: {{property.landlord.address}}</p>
<h3>From Rental property</h3>
<ul>
{% for rental in property.landlord.rentalpropertys.all %}
<br>
<li>Title: {{property.title}}</li>
<img src="{{property.image.url}}" height="200" alt=""/>
<li>created at: {{property.created_at}}</li>
<li>Type of property: {{property.type_of_property_listing}}</li>
<li>Street: {{property.street}}</li>
<li>Borough: {{property.borough}}</li>
<ul>
{% for contract in rental.contracts.all %}
<li> Insurance required: {{contract.insurance_required}}</li>
<li> other terms: {{contract.other_terms}}</li>
{% endfor %}
</ul>
{% endfor %}
</ul>
第二种解决方案:
views.py
class DetailView(generic.DetailView):
model = RentalProperty
template_name = 'rental/detail.html'
context_object_name = 'property'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['landlord']= Landlord.objects.all()
context['contract']= Contract.objects.filter(rentalproperty__title=title).order_by('created_at')
return context
post 功能是一样的。
detail.html
<h1>This is the detail view</h1>
<h3>From landlord</h3>
<p>Landlord: {{property.created_by}}</p>
<p>address: {{property.landlord.address}}</p>
<h3>From Rental property</h3>
<ul>
<li>Title: {{property.title}}</li>
<img src="{{property.image.url}}" height="200" alt=""/>
<li>created at: {{property.created_at}}</li>
<li>Type of property: {{property.type_of_property_listing}}</li>
<li>Street: {{property.street}}</li>
<li>Borough: {{property.borough}}</li>
</ul>
<ul>
{% for data in contract %}
<li> insurance : {{data.insurance_required}}</li>
<li> other terms: {{data.other_terms}}</li>
{% endfor %}
</ul>
我的模特:
class Landlord(models.Model):
user = models.OneToOneField(UserModel, on_delete=models.CASCADE)
address = models.CharField(max_length=255)
def __str__(self):
return str(self.address)
class RentalProperty(models.Model):
landlord = models.ForeignKey("Landlord", related_name='rentalpropertys', on_delete=models.CASCADE)
created_by = models.ForeignKey(UserModel, related_name='rentalpropertys', on_delete=models.CASCADE)
title = models.TextField(unique=True)
created_at = models.DateTimeField(auto_now_add=True)
PROPERTY_LISTING_CHOICES = Choices(
('APARTMENT', _('Apartment')),
('HOLIDAY_HOME', _('Holiday home')),
('SINGLE_FAMILY_HOME', _('Single family home')),
('COMMERCIAL', _('Commercial')),
)
type_of_property_listing = models.CharField(
max_length = 50,
choices = PROPERTY_LISTING_CHOICES,
default = PROPERTY_LISTING_CHOICES.APARTMENT,)
street = models.CharField(max_length=255)
borough = models.CharField(max_length=255)
image = models.ImageField(upload_to='images/', null=True, blank=True,)
def __str__(self):
return str(self.title)
class Contract(models.Model):
rentalproperty = models.ForeignKey("RentalProperty", related_name='contracts', on_delete=models.CASCADE)
insurance_required = models.BooleanField(default=True)
other_terms = models.TextField(blank=True)
def __str__(self):
return str(self.insurance_required)
第一个解决方案输出:
地址:赫尔辛基 标题:构建应用程序 保险:是 - 这会重复多次。
第二解输出:
地址:赫尔辛基 标题:构建应用程序 保险:是 - 保险会重复多次
我的期望: 地址:赫尔辛基 标题:构建应用程序 保险:是的
感谢您的宝贵时间:)
【问题讨论】:
-
这是作业吗?如果不想保险细节重复,需要了解模板中
contract变量的内容是什么,for在做什么 -
@TimmyO'Mahony 不,这不是家庭作业。这是我正在构建的一个学习 Django 的项目。除了我不明白你的问题,for 是遍历数据并返回与 id 相关的特定对象,至少,这是我所期望的。
-
好的,你到底想显示什么?您想展示单个出租物业和一份合同(与该物业相关)?
-
@TimmyO'Mahony 完全正确。这是我的意图,但从第一个解决方案中,我获得了租赁财产和合同的多个实例,第二个解决方案获得了租赁财产的多个实例,但相关合同的多个实例。
-
知道了。你可以为
RentalProperty和Contract发布你的模型吗?您应该能够在模板中使用模板中的循环{% for contract in property.contract_set.all %}来循环仅遍历属于出租物业的合同。
标签: django django-models django-forms django-views django-templates