Accessing Many-to-Many Values Django - django

article = get_object_or_404(Article,slug=slug)
categories = article.category.all()
Using render_to_response() , how can I use the categories in the view ?

Assuming you have the article in the template, you can do the following:
# In your view
return render_to_response('page.html', {'article': article})
# In your template
{% for category in article.category.all %}
{{ category.attribute }}
{% endfor %}
# Or, if you already have the categories
return render_to_response('page.html', {'categories': categories})
{% for category in categories %}
{{ category.attribute }}
{% endfor %}

Related

multiple query model in same view django

I've been doing some django these past weeks and I'm having a problem.
I have a page where Articles are shown. No problem while reovering all articles from db. But now I'd like to get all categories (an Article has a category) that I have in my database.
So I can display like this in my page:
List of categories
-cat1
-cat2
-cat3
List of articles
-art1
-art2
-art3
But I don't know how to do with both queries.
Here's what I've tried.
class IndexView(generic.ListView):
template_name = 'eduardoApp/index.html'
context_object_name = 'article_list'
def get_queryset(self):
return Article.objects.order_by('article_name')
def get_categories(request):
category_list=Category.objects.all()
context = {'category_list':category_list}
return render(request,'eduardoApp/index.html',context)
And in my view:
<h2>List of categories</h2>
{% if category_list %}
{% for category in category_list %}
<p>{{ category.name }}</p>
{% endfor %}
{% else %}
<p>no categorys</p>
{% endif %}
<h2>List of articles</h2>
{% if article_list %}
<div class="flex-container">
{% for article in article_list %}
<div>{{ article.article_name }}</div>
{% endfor %}
</div>
{% else %}
<p>No articles...</p>
{% endif %}
{% endblock %}
In my view I keep seeing no categorys displayed (since category_list does not exist but don't know why and how to fix)
ListView is creating context with 'objects' as queryset get_queryset returns.
I suppose your custom method get_categories hasn't been used anywhere?
Best practice here is to override get_context_data method like...
class IndexView(generic.ListView):
...
def get_context_data(self, **kwargs):
context = super(IndexView, self).get_context_data(**kwargs)
context['category_list'] = ...
return context

Receiving a list of related models from the list of objects (bound by a foreign key). Django

I have two very simple classes for products and photos. I would like to present products on the main page of my store along with photos related to a foreign key. But I do not know how to do this, I found many answers to get this in the view using a join like 'prefetch_related' but my ID changes for each case. So how do you present your photos for each product? are there any Django tags about which I do not know?
my models.py
class Product(models.Model)
name = models.CharField(max_length=10)
class Image(models.Model)
image = models.ImageField()
name_related = models.ForeignKay(Product, on_delate=models.CASCADE)
views.py
def home(request):
product_list = Product.objects.all()[:12]
#img = ??
context = {'product_list': product_list,
}
return render(request, 'home.html', context)
home.html
{% for product in product_list %}
{{ product.name }}
<!-- {{ product.imge }} ' element presenting the first photo for each 'product' model'???-->
{% endfor %}
Any help will be appreciated.
Since a foreign relation has been established you can iterate through the related models from the parent model.
The related models are already accessible from the parent model without doing anything explicit.
In your template you can do this:
{% for product in product_list %}
{{ product.name }}
{% for product_image in product.image.all %}
<!-- Iterate through this products related images -->
{{ product_image.image.url }}
{% endfor %}
{% endfor %}
For performance reasons, you will want to prefetch the relations, or else for every product you will do an additional query, so, in your view you will want to add this:
product_list = Product.objects.all().prefetch_related('image')[:12]
Just do
{% for product in product_list %}
{{ product.name }}
{% for image in product.image.all %}
<!-- {{ image.image.url }} -->?
{% endfor %}
{% endfor %}

How to iterate queryset dictionary in django template

This is my dictionary i get from view:
{'questions_in_topic': <QuerySet [{'question_id__description': 'Describe your most significant leadership experience'}, {'questi
on_id__description': 'Which kind of leader are you?'}]>}
How do I show individual questions in django template?
The view is below:
def get_question_from_topic(request):
if request.method == "GET":
questions_in_topic = QuestionTopic.objects.filter(topic_id=request.GET['topicId']).values('question_id__description').order_by('question_id__description')
print(questions_in_topic)
context = { 'questions_in_topic': questions_in_topic }
print(context)
return render(request, 'recruiter/add_question_library.html', context)
return render(request, 'recruiter/add_question_library.html', context)
{% if questions_in_topic %}
{% for question in questions_in_topic %}
Question: {{ question }}
{% endfor %}
{% endif %}
If you're only accessing one field from the queryset then using values_list is probably better for your needs
Changing
questions_in_topic = QuestionTopic.objects.filter(topic_id=request.GET['topicId']).values('question_id__description').order_by('question_id__description')
To
questions_in_topic = QuestionTopic.objects.filter(topic_id=request.GET['topicId']).order_by('question_id__description').values_list('question_id__description', flat=True)
After this questions_in_topic will be a list of strings. You can then use these in your template like so
{% for question in questions_in_topic %}
Question: {{ question }}
{% empty %}
There are no questions.
{% endfor %}

what is the right way to query a manytomany field in django

so i have a model which is,
class Category(SmartModel):
item=models.ManyToManyField(Item)
title=models.CharField(max_length=64,help_text="Title of category e.g BreakFast")
description=models.CharField(max_length=64,help_text="Describe the category e.g the items included in the category")
#show_description=check box if description should be displayed
#active=check box if category is still avialable
display_order=models.IntegerField(default=0)
def __unicode__(self):
return "%s %s %s %s " % (self.item,self.title, self.description, self.display_order)
and as you may see, it has a manytomany field
item=models.ManyToManyField(Item)
i want to return all the items in a template, here is my views.py for this
def menu(request):
categorys= Category.objects.all()
items= categorys.all().prefetch_related('item')
context={
'items':items,
'categorys':categorys
}
return render_to_response('menu.html',context,context_instance=RequestContext(request))
here is how am doing it in the templates,
<ul>
{% for item in items %}
<li>{{ item.item }}
</li>
</ul>
{% endfor %}
after all this,this is what it is returning in my web page,
<django.db.models.fields.related.ManyRelatedManager object at 0xa298b0c>
what am i doing wrong,I have really looked around but all in vain, hoping you can help me out and thanking you in advance
Exactly, you have a many to many manager. You need to actually query something... like all()
{% for item in items %}
{% for i in item.item.all %}
{{ i }}
{% endfor %}
{% endfor %}
Based on your variable naming, I think you're confusing the results of prefetch_related as a bunch of items. It is in fact returning a QuerySet of Category objects.
So it would be more intuitive to call them categories.
{% for category in categories %}
{% for item in category.item.all %}
{{ item }} {# ...etc #}
Try to use:
categorys= Category.objects.prefetch_related('item').all()
And then in template:
{% for category in categorys %}
{% for item in category.item.all %}
{{ item }}
{% endfor %}
{% endfor %}

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.