現在、Django の学習を進めていますが、この問題を自分で解決する方法がわかりません。私は本Developers Library - Python Web Development With Djangoを読んでいます.1つの章で、2つのモデル(ストーリーとカテゴリ)、いくつかの汎用ビューとカスタムビュー、ビューのテンプレートを備えた単純なCMSシステムを構築しています。
この本には、ストーリー、ストーリーの詳細、および検索を一覧表示するためのコードのみが含まれています。それを拡張して、カテゴリとストーリーのネストされたリストを含むページを作成したいと考えました。
- Category1
-- Story1
-- Story2
- Category2
- Story3 etc.
カテゴリのリストに独自の一般的な object_list ビューを追加する方法を理解することができました。私の問題は、ストーリーが公開されているかどうかにかかわらず、ストーリーモデルに STATUS_CHOICES があり、デフォルトで公開ストーリーのみを取得するカスタムマネージャーがあることです。一般的なカテゴリ リスト ビューに、カスタム マネージャーも使用し、パブリック ストーリーのみをフェッチするように指示する方法がわかりません。その小さな問題を除いて、すべてが機能します。1 つのページでそのカテゴリのすべてのストーリーのサブ リストを含むすべてのカテゴリのリストを作成できます。唯一の問題は、リストに非公開のストーリーが含まれていることです。
ここで正しい軌道に乗っているかどうかはわかりません。私のurls.pyには、すべてのCategoryオブジェクトを取得する汎用ビューが含まれており、私のテンプレートでは、category.story_set.allを使用して、そのカテゴリのすべてのStoryオブジェクトを取得し、ループします。
テンプレートに if ステートメントを追加し、モデル ファイルの VIEWABLE_STATUS を使用して、リストするかどうかを確認することは可能だと思います。このソリューションの問題点は、DRY との互換性があまりないことです。
カテゴリで 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 %}
<h1>Categories</h1>
{% if category_list %}
<ul id="category-list">
{% for category in category_list %}
<li><a href="{{ category.get_absolute_url }}">{{ category.label }}</a></li>
{% if category.story_set %}
<ul>
{% for story in category.story_set.all %}
<li><a href="{{ story.get_absolute_url }}">{{ story.title }}</a></li>
{% endfor %}
</ul>
{% endif %}
{% endfor %}
</ul>
{% else %}
<p>
Sorry, no categories at the moment.
</p>
{% endif %}
{% endblock %}