【问题标题】:How to get a single model object with a relation to the template in Django如何在 Django 中获取与模板相关的单个模型对象
【发布时间】: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 完全正确。这是我的意图,但从第一个解决方案中,我获得了租赁财产和合同的多个实例,第二个解决方案获得了租赁财产的多个实例,但相关合同的多个实例。
  • 知道了。你可以为RentalPropertyContract 发布你的模型吗?您应该能够在模板中使用模板中的循环 {% for contract in property.contract_set.all %} 来循环仅遍历属于出租物业的合同。

标签: django django-models django-forms django-views django-templates


【解决方案1】:

在@Timmy O'Mahony 回答的帮助下,我使用第一个解决方案在我的模板中执行了 {% for contract in property.contracts.all %} 并且它有效。合同是出租物业的相关名称。谢谢大家。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-24
    • 2012-05-21
    • 2018-03-29
    • 2011-01-15
    • 1970-01-01
    • 2014-09-07
    • 2017-08-06
    相关资源
    最近更新 更多