Reputation: 45
I am trying to display the data from one of my models to the DetailView using the related name defined in the model. It works for the Rental Property model but it doesn't work for the contract model. What might seems to be the problem?
A little context to what I am trying to achieve. To get the attribute's value of the rental model, I use a for loop on landlord.rentalproperty.all; rentalproperty been the related name to the landlord model. This work perfectly.
Where I am having a problem is when I use the contract model related name to rentalproperty, this doesn't work. How can I fixed that? Thanks.
my model:
UserModel = get_user_model()
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='rentalproperty', on_delete=models.CASCADE)
created_by = models.ForeignKey(UserModel, related_name='rentalproperty', on_delete=models.CASCADE)
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)
def __str__(self):
return str(self.type_of_property_listing)
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)
My html:
<h1>This is the detail view</h1>
<h3>From landlord</h3>
<p>Address: {{landlord.address}}</p>
<h3>From Rental property</h3>
<ul>
{% for rental in landlord.rentalproperty.all %}
<li>landlord: {{rental.landlord}}</li>
<li>createdby: {{rental.created_by}}</li>
<li>Type of property: {{rental.type_of_property_listing}}</li>
<li>Street: {{rental.street}}</li>
<li>Borough: {{rental.borough}}</li>
{% endfor %}
</ul>
<ul>
{% for contract in rentalproperty.contracts.all %}
<li> rental property: {{contract.rentalproperty}}</li>
{% endfor %}
</ul>
My detail View.
class DetailView(generic.DetailView):
model = Landlord
template_name = 'rental/detail.html'
Upvotes: 0
Views: 886
Reputation: 4419
DetailView
view:class RentalPropertyDetailView(DetailView):
context_object_name = 'property'
model = models.RentalProperty
Notice the "context_object_name" attribute.
Second, your template is a little confusing.. Why would you want to loop for one landlord, listing the landlord's name again for each of its rental properties. And the the same for each contract?
rentalproperty_detail.html
template:<h1>This is the detail view</h1>
<h3>From landlord: {{ property.created_by }}</h3>
<p>Address: {{ property.landlord.address }}</p>
<h3>From Rental property</h3>
<ul>
{% for rental in property.landlord.rental_properties.all %}
<br>
<li>createdby: {{rental.created_by}}</li>
<li>Type of property: {{rental.type_of_property_listing}}</li>
<li>Street: {{rental.street}}</li>
<li>Borough: {{rental.borough}}</li>
<ul>
{% for contract in rental.contracts.all %}
<li> Insurance required: {{contract.insurance_required}}</li>
{% endfor %}
</ul>
{% endfor %}
</ul>
models.py
:class RentalProperty(models.Model):
landlord = models.ForeignKey("Landlord", related_name='rental_properties', on_delete=models.CASCADE)
created_by = models.ForeignKey(User, on_delete=models.CASCADE)
PROPERTY_LISTING_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 = 'APARTMENT',
)
street = models.CharField(max_length=255, default=None, null=True)
borough = models.CharField(max_length=255, default=None, null=True)
def __str__(self):
return str(self.type_of_property_listing)
class Contract(models.Model):
rental_property = 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)
The Landlord
model I left it the same.
urls.py
you should fetch one (1) RetailProperty
like:url(r'^property/(?P<pk>\d+)$', views.RentalPropertyDetailView.as_view(), name='property-detail'),
This will output the following:
Upvotes: 2