ForeignKey, show values in template - django

I have two classes:
class People
name = CharField()
class Equipment
name = Charfield()
responsible = ForeignKey(People)
and view:
def persone_detail(request, tab_number):
return direct_to_template(request, 'person.html', {
'persone': Peoples.objects.filter(tab_number=tab_number)
How can I show in template the name from equipment?

By following the reverse relationship to Equipment:
http://docs.djangoproject.com/en/dev/topics/db/queries/#following-relationships-backward
{% for person in persone %}
Person: {{ person.name }}
{% for equipment in person.equipment_set.all %}
Equipment: {{ equipment.name }}
{% endfor %}
{% endfor %}

Related

Get aggregate in a template

I have this Django model:
class Location(models.Model):
name = models.CharField(primary_key=True, max_length=100)
customer = models.OneToOneField(Customer, default=None)
class Customer(models.Model):
name = models.CharField(primary_key=True, max_length=100)
class Order(models.Model):
amount = models.PositiveIntegerField(default=0)
customer = models.ForeignKey(Customer, default=0)
in my view I get them like this:
locations = models.Location.objects.all()
and the template lists them like this:
{% for location in locations %}
{{ location.customer.name }}
{% endfor %}
I would like to add a sum of all amount of all Orders connected that customer, something like:
{% for location in locations %}
{{ location.customer.name }} ordered {{ location.customer.orders.sum(amount) }} items
{% endfor %}
And according to this question, I should do that in the view, but how?
You should use .annotate (look in docs):
from django.db.models import Count
customers = models.Customer.objects.annotate(orders_count=Count('order'))
Then in templates you can use it like this:
{% for customer in customers %}
{{ customer.name }} ordered {{ customer.orders_count }} items
{% endfor %}
After some folling around I found this works:
locations = models.Location.objects.annotate(num_order=Count('customer__order'))
and then use this in the template:
{% for location in locations %}
{{ location.customer.name }} ordered {{ location.num_order }} items
{% endfor %}

Template not rendering correctly while iterating through foreign keys

I am trying to iterate over my FKs in my model such that I show all the connections through various tables. My template renders but does not show any values. Any ideas?
models.py
class State(models.Model):
state = models.CharField(max_length=255)
relevantdisease = models.ForeignKey(Disease)
relevantoption = models.ManyToManyField(Option, through='StateOption')
class StateOption(models.Model):
partstate = models.ForeignKey(State)
partoption = models.ForeignKey(Option)
relevantoutcome = models.ManyToManyField(Outcome, through='StateOptionOutcome')
class StateOptionOutcome(models.Model):
stateoption = models.ForeignKey(StateOption)
relevantoutcome = models.ForeignKey(Outcome)
outcomevalue = models.CharField(max_length=20)
views.py
def stateall(request, disease_id):
disease = get_object_or_404(Disease, pk=disease_id)
states = State.objects.select_related().filter(relevantdisease=disease_id)
context = {'disease':disease,'states': states}
return render(request, "stateall.html", context)
template.html
{% for state in states %}
<li>{% for i in state.stateoption_set.all %}</li>
<li>{% for j in i.stateoptionoutcome_set.all %}</li>
{% endfor %}
{% endfor %}
{% endfor %}
I would like the template to show up as:
State1<state>
<li>partoption</li>
<li>relevantoutcome: outcomevalue</li>
State2<state>
<li>partoption</li>
<li>relevantoutcome: outcomevalue</li>
...
Your template never outputs anything.
You're probably misunderstanding the use of the {% for %} template tag.
This:
<li>{% for j in i.stateoptionoutcome_set.all %}</li>
{% endfor %}
Outputs <li> a few times.
But this:
{% for j in i.stateoptionoutcome_set.all %}
<li>{{ j.relevantoutcome }}: {{ j.outcomevalue }}</li>
{% endfor %}
Will output a line per StateOptionOutcome found in i.stateoptionoutcome_set.all.

Iterate set in template

I have this models:
class House(models.Model):
name = models.CharField()
class BedRoom(models.Model):
name = models.CharField()
class Catalog(models.Model):
name = models.CharField()
house = models.ForeignKey(House)
bedroom = models.ForeignKey(BedRoom)
at admin.py Catalog is inline to House
class CatalogInline(admin.TabularInline):
model = Catalog
class HomeAdmin(admin.ModelAdmin):
inline = [CatalogInline]
then I need obtain at view the list of Bedrooms from House Catalog, at Home model I have:
def bedrooms(self):
return self.catalog_set.all()
but when I do at template obtaining "houses" from a view:
{% for house in houses %}
{% for h in house %}
<p>{{h.name}}</p>
{% endfor %}
{% endfor %}
I get an error:
'Catalog' object is not iterable
what I'm doing wrong?
I should define the model in a different way?
As I mentioned, you don't seem to actually be calling the bedrooms method. I guess (and it is just a guess) you mean this:
{% for house in houses %}
{% for h in house.bedrooms %}
<p>{{h.name}}</p>
{% endfor %}
{% endfor %}
The bedrooms method is pointless though, as you can just as easily do this:
{% for house in houses %}
{% for h in house.catalog_set.all %}
<p>{{h.name}}</p>
{% endfor %}
{% endfor %}

How to print ordered submodel in template?

I have models:
class Model_1(models.Model):
name = models.CharField(...
pos = models.IntegerField(...
class Model_2(models.Model):
...
m1 = models.ManyToManyField(Model_1,...
and I print this in template:
{% for m2 in model2 %}
{% for m1 in m2.m1.all %}
{{ m1.name }}
{% endfor %}
{% endfor %}
but I want to print m1.names ordered by 'pos' field. How to do it?
in the model you can specify ordering of the objects. More here
class M1():
...
class Meta:
ordering = ['pos']

Can't use Django's get_absolute_url in dictionary of dictionaries?

I'm having some trouble using get_absolute_url in a template. It seems to work fine if I just pass in one of my store objects and say {{ store.get_absolute_url }}, but if I have to iterate through a dictionary of stores and then use the get_absolute_url function, it returns nothing. Exactly what I'm doing is below:
class Store(EthicalObject):
type = "Store"
name = models.CharField(max_length=50)
company = models.ForeignKey(Company, verbose_name="Company", null=True, blank=True)
location = models.OneToOneField(Location, verbose_name="Location", null=True, blank=True)
products = models.ManyToManyField('Product', related_name="%(class)s_related", db_table=u'ethicsdb_products_to_stores', blank=True)
companies = models.ManyToManyField('Company', related_name="%(class)s_related", db_table=u'ethicsdb_companies_to_stores', blank=True)
def get_absolute_url(self):
return ('store_details', [str(self.id)])
get_absolute_url = models.permalink(get_absolute_url)
This works:
views.py:
def fetch_sidebar_data(shop_object):
sidebar_modules = {}
if shop_object.content_type.name == 'company':
sidebar_modules['related_stores'] = shop_object.stores.all()
sidebar_modules['related_products'] = shop_object.products.all()
if shop_object.content_type.name == 'store':
sidebar_modules['related_companies'] = shop_object.companies.all()
sidebar_modules['related_products'] = shop_object.products.all()
if shop_object.content_type.name == 'product':
sidebar_modules['related_stores'] = shop_object.stores.all()
sidebar_modules['related_companies'] = shop_object.companies.all()
sidebar_modules['tags'] = shop_object.tags
return sidebar_modules['related_stores'][1]
def company_details(request, company_id):
company = get_object_or_404(Company, id=company_id)
sidebar_modules = fetch_sidebar_data(company)
return render_to_response('company/details.html', {'company': company, 'sidebar_modules': sidebar_modules}, context_instance=RequestContext(request))
template:
{% extends "base-onecol.html" %}
{% block page_div_extra_attr %}class="twocol"{% endblock %}
{% block sidebar_content %}
<div id="sidebar-right">
<h1>{{ sidebar_modules.name }}{{sidebar_modules.get_absolute_url }}</h1>
</div>
{% endblock %}
This doesn't work:
views.py:
def fetch_sidebar_data(shop_object):
sidebar_modules = {}
if shop_object.content_type.name == 'company':
sidebar_modules['related_stores'] = shop_object.stores.all()
sidebar_modules['related_products'] = shop_object.products.all()
if shop_object.content_type.name == 'store':
sidebar_modules['related_companies'] = shop_object.companies.all()
sidebar_modules['related_products'] = shop_object.products.all()
if shop_object.content_type.name == 'product':
sidebar_modules['related_stores'] = shop_object.stores.all()
sidebar_modules['related_companies'] = shop_object.companies.all()
sidebar_modules['tags'] = shop_object.tags
return sidebar_modules
template:
{% extends "base-onecol.html" %}
{% block page_div_extra_attr %}class="twocol"{% endblock %}
{% block sidebar_content %}
<div id="sidebar-right">
{% for module_name,module in sidebar_modules.items %}
{% ifequal module_name "related_stores" %}
<h3>Sold Here</h3>
{% for related_store in module.values %}
{{ related_store.name }}<br/>
{% endfor %}
{% endifequal %}
{% ifequal module_name "related_products" %}
<h3>Buy Local</h3>
{{ module }}<br/>
{% endifequal %}
{% ifequal module_name "related_companies" %}
<h3>
{{ module }}<br/>
{% endifequal %}
{% ifequal module_name "tags" %}
{{ module }}<br/>
{% endifequal %}
{% endfor %}
</div>
{% endblock %}
In the second one, I just get no return from get_absolute_url. I know it's working in other places when I print it out. Is this a Django bug, the inability to use get_absolute_url in a dictionary of dictionaries?
Wow, that was a rather convoluted question.
Your problem is here: {% for related_store in module.values %}
module is a QuerySet. .values is calling the QuerySet method which returns a dictionary containing the field values for each row. A dictionary has no get_absolute_url attribute, and get_absolute_url isn't a field in the model.
Just use {% for related_store in module %} and you'll be dealing with actual model instances rather than dictionaries, which means {{ related_store.get_absolute_url }} will work fine.