I am somewhat new to Django and have searched for some simple examples of creating objects with subobjects in views so that in templates I can have nested for loops.
Here is my models.py for this application…
from django.db import models
from django import forms
class Market(models.Model):
name = models.CharField('Market name', max_length=150)
state = models.CharField('State', max_length=2)
def __unicode__(self):
return self.name
class Location(models.Model):
name = models.CharField('Location name', max_length=150)
address1 = models.CharField('Address 1', max_length=200)
address2 = models.CharField('Address 2', max_length=200,blank=True)
city = models.CharField('City', max_length=100)
state = models.CharField('State', max_length=2)
zip_code = models.CharField('ZIP', max_length=10)
phone = models.CharField('Phone', max_length=20)
hours = models.TextField('Hours of operation', max_length=255)
quote_text = models.TextField('Customer quote', max_length=500)
quote_by = models.CharField('Customer name', max_length=30)
yelp_url = models.URLField('Yelp URL', max_length=300,blank=True)
image_store = models.ImageField('Storefront image', upload_to='images/locations', max_length=300,blank=True)
image_staff = models.ImageField('Staff image', upload_to='images/locations', max_length=300,blank=True)
market = models.ForeignKey(Market, verbose_name='Regional market', null=True)
def __unicode__(self):
return self.name
Markets data may look as follows…
id = 1
state = 'MO'
name = 'St. Louis - Central'
id = 2
state = 'MO'
name = 'St. Louis - West'
id = 3
state = 'IL'
name = 'Chicago - South'
id = 4
state = 'IL'
name = 'Chicago - North'
In my views.py I’d like to create an object with a list/array of grouped Market states (distinct) in descending order, each with a subarray of the individual Market names in that State in order to complete a nested forloop in the template.
The templating language in Django is really cool in how it prevents a ton of logic from residing betwixt the html, which I like. But I am still wrapping my head around both Python syntax and the need to create all objects exactly the way they need to iterate in the template.
Here’s what views.py looks like …
def locations_landing(request):
marketList = Market.objects.values('state').order_by('-state').distinct()
return render_to_response('locations.html', locals())
How to return an object so that my template can perform the following nested looping…
{% for st in stateList.all %}
<h4>{{ st.state }}</h4>
{% for mkt in stateList.marketList.all %}
<p>* <a href="#">{{ mkt.name }}</a></p>
{% endfor %}
{% endfor %}
This would result in the following rendered in html based on my data samples above…
<h4>MO</h4>
<p>* St. Louis - Central</p>
<p>* St. Louis - West</p>
<h4>IL</h4>
<p>* Chicago - South</p>
<p>* Chicago - North</p>
BTW, there are no errors in any of the .PY code samples above, all is well, I just need some guidance on creating the object correctly in the view so the template does it’s thing.
I don’t see a need to use
distincthere. By representing the states as separate model and using relations you would gain much more flexibility.I suggest you create a third
Statemodel and use a ForeignKey to relate the models together so that eachMarkethas a one to many relation to singleState, i guess you also wantLocationmodel related to theMarketmodel.In your view, all you need to do is take all the states and pass them into the template:
And finally, in your template, iterate over the state list and use a backward relation queryset to get all the markets in that state: