set_all to get value from custom model manager in django - django

I have two models:
Tutorial
--> consist of published manager which returns queryset when is_published=True
Category
In template, I am passing Category object.
{% for category in categories %}
{% for tutorial in category.tutorial_set.all %}
{{ tutorial.title }}
{% endfor %}
{% endfor %}
Instead of getting all, I want to get from published manager like: Tutorials.published.all()
How to achieve this?

Well I guess you can do something like
class TutuorialManager(models.Manager):
def published(self):
return self.filter(is_published = True)
then in the views you can do something like..
{% for category in categories %}
{% for tutorial in category.tutorial_set.published.all %}
{{ tutorial.title }}
{% endfor %}
{% endfor %}

Related

Iterate through Django queryset within template

I have created a custom filter that returns a queryset of objects.
in: templatetags
#register.filter(name = 'create_html_for_deleting_notes')
def create_html_for_deleting_notes(task_pk):
corresponding_notes = Note.objects.filter(its_task = Task.objects.filter(pk = task_pk))
return(corresponding_notes)
in template:
{% for corresponding_task in corresponding_tasks %}
<h5>{{ corresponding_task | create_html_for_deleting_notes }}<h5/>
{% endfor %}
This works in printing out my queryset. I would like to iterate through that queryset, something like:
in template:
{% for corresponding_task in corresponding_tasks %}
{% for note in corresponding_task | create_html_for_deleting_notes %}
{{ note }}
{% endfor %}
{% endfor %}
But this gives me the error 'for statements should use the format "for x in y"'
Thank you for the help!
You need to remove the spaces around the filter | character.
However, I don't think you need the filter at all. You didn't post your model, but it seems like you have a foreignkey relationship between Task and Note, so you should just use the reverse accessor:
{% for corresponding_task in corresponding_tasks %}
{% for note in corresponding_task.note_set.all %}
{{ note }}
{% endfor %}
{% endfor %}

django view - all categories and all entries

I'm trying to build a page with all of the model's categories and associated entries in one view. I followed tips from here django class based views for all categories with all entires and here Get all categories and items in category but I still can't get it to work. Any ideas ?
-- models
class Category(models.Model):
name = models.CharField(max_length=50)
def __unicode__(self):
return self.name
class Feed(models.Model):
name = models.CharField(max_length=100)
url = models.CharField(max_length=100)
category = models.ForeignKey(Category)
user = models.ManyToManyField(User)
def __unicode__(self):
return self.url
-- views
def category_page(request):
object_list = Category.objects.all()
context = {'object_list': object_list,}
return render(request, 'category_page.html', context)
-- template category_page.html
{% block content %}
{% for category in object_list %}
{{ category.name }}
{% for entry in category.entry_set.all %}
{{ category.name}}
{% endfor %}
{% endfor %}
{% endblock content %}
I'm getting list of all categories displayed but no entries.
thanks
-M
Here
{% for entry in category.entry_set.all %}
{{ category.name}}
{% endfor %}
should be
{% for entry in category.feed_set.all %}
{{ entry.name}}
{% endfor %}
{{ category.name}} inside the forloop for entries is what is not displaying the correct name.
Also, what is entry_set ? If you are not specifying a related_name, you need to use the lower-case model name to get the related objects (feed_set in this case).
Something like this:
category.feed_set.all
Summing it up,
{% block content %}
{% for category in object_list %}
{{ category.name }}
{% for entry in category.feed_set.all %}
{{ entry.name}}
{% endfor %}
{% endfor %}
{% endblock content %}
You can read more on related objects here
If this is your actual code, the problem is variable names in your template.
{% for category in object_list %}
{{ category.name }}
{% for entry in category.feed_set.all %}
{{ entry.name}}
{% endfor %}
{% endfor %}
Specifically, you refer to entry_set, but that's not the reverse name for the relationship since your model name is Feed rather than Entry and you haven't declared a non-default related_name argument.
Also, you're re-printing your category name instead of the name of the Feed instances.

Using custom object manager on related set

Im trying to print out 4 entries. It works, as long I don't have any entries not published.
How can I get a queryset that only contains objects from my "published" manager?
Now I use: {% if benefit.status == "p" %} to not print those entries not published, but then the unpublished effects the slice count.
#views.py:
class PackageListFrontpage(ListView):
context_object_name = "package_frontpage_list"
template_name = "frontpage.html"
queryset = Package.published.all().order_by('order')[:5]
#frontpage.html
{% for package in package_frontpage_list %}
<div>
<h3>{{ package.name }} >></h3>
<ul>
{% for benefit in package.benefit_set.all|slice:":4" %}
{% if benefit.status == "p" %}
<li>{{ benefit.name }}</li>
{% endif %}
{% empty %}
<li>There are no published benefits in this package</li>
{% endfor %}
</ul>
</div>
{% endfor %}
I guess there is a better way of doing this?
You could define a method on your Package model that returns the queryset of related benefits which are published.
class Package(object):
...
def benefit_set_published(self):
"""
Return the related benefits which are published
"""
return self.benefit_set.filter(status="p")
Then change your template to:
{% for benefit in package.benefit_set_published.all|slice:":4" %}
<li>{{ benefit.name }}</li>
{% empty %}
<li>There are no published benefits in this package</li>
{% endfor %}

Problem with django templates

Is there any solution to do something like this:
{% for c in categories %}
{% for s in c.subcategory_set %}
<li>{{ s.name }}</li>
{% endfor %}
{% endfor %}
???
Reverse relations on a FK have a manager. As such, you need to use the all() method if you want to access all related objects.
{% for s in c.subcategory_set.all %}

Dictionary with arrays in django templates

I have dictionary with arrays inside:
dicarr = {'category': ['post1','post2', 'e.g.'], 'category2': ['post1','post2']}
Array is filled in one cycle:
dicarr = {}
for category in Categories.objects.all():
category_posts = Post.objects.filter(category=category)
dicarr[category] = [post for post in category_posts ]
How can i get access to array from django template? I tried:
{% for arrdic in dicarr %}
{{ arrdic.name }}
{% for i in arrdic.posts %}
{{ i.name }}
{% endfor %}
{% endfor %}
But isn't working.
Assuming you have a foreign key pointing to Category on your Post, you don't even need to do it this complicated. All you need to is pass this to the template:
categories = Category.objects.all()
Then you can iterate like this in the template:
{% for category in categories %}
{{ category.name }}
{% for post in categories.post_set.all %}
{{ post.name }}
{% endfor %}
{% endfor %}
You can do this with any foreign key relationships. Hope that answers your question!
Following your original code, your template should be (also see for tag docs):
{% for category, posts in dicarr.items %}
{{ category.name }}
{% for post in posts %}
{{ post.name }}
{% endfor %}
{% endfor %}
But this isn't the best way to do this, because your view will produce number of queries equal to the number of categories. See my answer to a similar question for a more efficient solutions.