问题
I have tried this for a couple of hours, and looked at alot of documentation, but I cant get it right. I dont think I'll see a solution to this anytime soon, so maybe someone could see what is wrong?
I want a view to show all my categories and all my connected entries to those categories.
I have tried to follow this example: django class-based-views topic
But I get this error: tuple index out of range
My model:
STATUS_CHOICES = (
('d', 'Draft'),
('p', 'Published'),
('w', 'Whitdrawn'),
)
class PublishedManager(models.Manager):
use_for_related_fields = True
def get_query_set(self):
return super(PublishedManager, self).get_query_set().filter(status='p')
class Category(models.Model):
name = models.CharField()
slug = models.SlugField()
status = models.CharField(max_length=1, default='d', choices=STATUS_CHOICES)
published = PublishedManager()
class Entry(models.Model):
name = models.CharField()
slug = models.SlugField()
category = models.ForeignKey(Category)
status = models.CharField(max_length=1, default='d', choices=STATUS_CHOICES)
published = PublishedManager()
My urls
#View for all categories and all connected entries
url(r'^blog/$', AllCategories.as_view()),
#View for one category - and all the connected entries
url(r'^blog/(?P<slug>[-\w]+)/$', CategoryList.as_view()),
My views
class AllCategories(ListView):
context_object_name = "category_list"
queryset = Category.published.all()
class CategoryList(ListView):
template_name = 'blog/category_and_connected_entries.html'
def get_queryset(self):
self.category = get_object_or_404(Category, self=self.kwargs['slug'])
return Entry.published.filter(category=self.category)
def get_context_data(self, **kwargs):
# Call the base implementation first to get a context
context = super(CategoryList, self).get_context_data(**kwargs)
# Add in the category
context['category'] = self.category
return context
Any help is much appreciated!
Edit:
Added my custom manager. I only have problems not showing unpublised entires in my template for listing all my categories and all their connected entires like:
- Category 1
- Published entry 1
- Published entry 3
- Category 2
- Published entry 7
- Published entry 9
I use this for loop getting the connected entires, but it also list the unpublised entires:
{% for entry in category.entry_set.all %}
回答1:
You can use _set.all, my code:
views.py
class Categories(models.Model):
model = Category
template_name = "#..."
paginate_by = #...
template
Categories list:
{% for category in object_list %}
Name: {{ category }}
{% for entry in category.entry_set.all|slice:":2" %}
{{ entry }}
{% empty %}
None
{% endfor %}
{% endfor %}
回答2:
You get this mistake because the self.args
which is a tuple of all the positional arguments is empty since you have not specified a group in your urls and you are trying to get the first element of an empty tuple(self.args[0]
)
Change your url to:url(r'^blog/(\w+)/$', CategoryList.as_view())
,
in order to be able to capture the category using self.args[0]
Copying from the docs:
The key part to making this work is that when class-based views are called, various useful things are stored on self; as well as the request (self.request) this includes the positional (self.args) and name-based (self.kwargs) arguments captured according to the URLconf.
Apart from this i don't see any other mistake in your code.
回答3:
As per your comment if you just wanting to show all category with related entry then all you need to do is fetch all category with
def query_set(self):
return Category.objects.all()
Then in your template just loop over the categories and nested loop for entries
{% for category in object_list %}
<ul>
<li>{{ category.name }}</li>
{% for entry in category.entry_set.all %}
<li>{{ entry }}</li>
{% endfor %}
</ul>
{% endfor %}
来源:https://stackoverflow.com/questions/12519678/django-class-based-views-for-all-categories-with-all-entires