我目前正在学习Django,但我无法弄清楚如何自己解决这个问题.我正在阅读" 开发人员库 - 使用Django进行Python Web开发 "一书,在一章中,您将构建一个包含两个模型(故事和类别)的简单CMS系统,一些通用和自定义视图以及视图模板.
该书仅包含列出故事,故事细节和搜索的代码.我想扩展它并构建一个包含类别和故事的嵌套列表的页面.
- Category1 -- Story1 -- Story2 - Category2 - Story3 etc.
我设法弄清楚如何为类别列表添加我自己的通用object_list视图.我的问题是,如果Story是公开的,则Story模型具有STATUS_CHOICES,并且自定义管理器只会默认获取公共Stories.我无法弄清楚如何告诉我的通用类别列表视图也使用自定义管理器,只获取公共故事.一切都有效,除了那个小问题.我能够在一个页面上为所有类别的故事创建所有类别的列表,唯一的问题是该列表包含非公共故事.
我不知道我是否走在正确的轨道上.我的urls.py包含一个抓取所有Category对象的通用视图,在我的模板中我使用category.story_set.all来获取该类别的所有Story对象,然后我循环.
我认为可以在模板中添加if语句,并使用模型文件中的VIEWABLE_STATUS来检查是否应该列出它.该解决方案的问题在于它与DRY不兼容.
是否有可能为Category模型添加某种管理器,只有在类别上使用story_set时才会获取公共Story对象?
或者这是解决我的问题的错误方法?
相关代码
urls.py(仅限类别列表视图):
urlpatterns += patterns('django.views.generic.list_detail', url(r'^categories/$', 'object_list', {'queryset': Category.objects.all(), 'template_object_name': 'category' }, name='cms-categories'),
models.py:
from markdown import markdown import datetime from django.db import models from django.db.models import permalink from django.contrib.auth.models import User VIEWABLE_STATUS = [3, 4] class ViewableManager(models.Manager): def get_query_set(self): default_queryset = super(ViewableManager, self).get_query_set() return default_queryset.filter(status__in=VIEWABLE_STATUS) class Category(models.Model): """A content category""" label = models.CharField(blank=True, max_length=50) slug = models.SlugField() class Meta: verbose_name_plural = "categories" def __unicode__(self): return self.label @permalink def get_absolute_url(self): return ('cms-category', (), {'slug': self.slug}) class Story(models.Model): """A hunk of content for our site, generally corresponding to a page""" STATUS_CHOICES = ( (1, "Needs Edit"), (2, "Needs Approval"), (3, "Published"), (4, "Archived"), ) title = models.CharField(max_length=100) slug = models.SlugField() category = models.ForeignKey(Category) markdown_content = models.TextField() html_content = models.TextField(editable=False) owner = models.ForeignKey(User) status = models.IntegerField(choices=STATUS_CHOICES, default=1) created = models.DateTimeField(default=datetime.datetime.now) modified = models.DateTimeField(default=datetime.datetime.now) class Meta: ordering = ['modified'] verbose_name_plural = "stories" def __unicode__(self): return self.title @permalink def get_absolute_url(self): return ("cms-story", (), {'slug': self.slug}) def save(self): self.html_content = markdown(self.markdown_content) self.modified = datetime.datetime.now() super(Story, self).save() admin_objects = models.Manager() objects = ViewableManager()
category_list.html(相关模板):
{% extends "cms/base.html" %} {% block content %}Categories
{% if category_list %}
Sorry, no categories at the moment.
{% endif %} {% endblock %}
Jonny Buchan.. 11
我发现文档有点不清楚,但属性可能正是你要找的.当您尝试它时,请注意此功能使用,它始终指向Model类中声明的第一个Manager,而不管它给出的是什么属性名称.您始终可以通过覆盖相应类中的方法来自定义管理站点中可编辑的项目.use_for_related_fields
Manager
_default_manager
queryset
ModelAdmin
失败了......
class Category(models.Model): def public_stories(self): return Story.objects.filter(category=self)
...和...
{% for story in category.public_stories %}
这至少避免了重复确定哪些故事可见的逻辑.
我发现文档有点不清楚,但属性可能正是你要找的.当您尝试它时,请注意此功能使用,它始终指向Model类中声明的第一个Manager,而不管它给出的是什么属性名称.您始终可以通过覆盖相应类中的方法来自定义管理站点中可编辑的项目.use_for_related_fields
Manager
_default_manager
queryset
ModelAdmin
失败了......
class Category(models.Model): def public_stories(self): return Story.objects.filter(category=self)
...和...
{% for story in category.public_stories %}
这至少避免了重复确定哪些故事可见的逻辑.