gpt4 book ai didi

模型中 _set 的 Django 管理器

转载 作者:行者123 更新时间:2023-12-03 18:21:33 25 4
gpt4 key购买 nike

我目前正在学习 Django,但我不知道如何自己解决这个问题。我正在阅读 Developers Library - Python Web Development With Django 一书,在一章中,您构建了一个简单的 CMS 系统,其中包含两个模型(故事和类别)、一些通用 View 和自定义 View 以及 View 模板。

本书只包含列出故事、故事细节和搜索的代码。我想对此进行扩展并构建一个包含类别和故事的嵌套列表的页面。

- Category1
-- Story1
-- Story2
- Category2
- Story3 etc.

我设法弄清楚如何为类别列表添加我自己的通用 object_list View 。我的问题是,如果 Story 是否公开,Story 模型具有 STATUS_CHOICES,并且默认情况下只会获取公共(public) Stories 的自定义管理器。我不知道如何告诉我的通用类别 ListView 也使用自定义管理器并且只获取公共(public)故事。除了那个小问题,一切正常。我可以为所有类别创建一个列表,并在单个页面上为该类别中的所有故事创建一个子列表,唯一的问题是该列表包含非公开故事。

我不知道我是否在正确的轨道上。我的 urls.py 包含一个通用 View ,它获取所有 Category 对象,在我的模板中,我使用 category.story_set.all 来获取该类别的所有 Story 对象,然后循环遍历。

我认为可以在模板中添加一个 if 语句并使用我的模型文件中的 VIEWABLE_STATUS 来检查它是否应该被列出。该解决方案的问题在于它不是非常兼容 DRY。

是否也可以为 Category 模型添加某种管理器,仅在使用 category 上的 story_set 时才会获取公共(public) Story 对象?

或者这是攻击我的问题的错误方法?

相关代码

urls.py(仅类别 ListView ):
urlpatterns += patterns('django.views.generic.list_detail',
url(r'^categories/$', 'object_list', {'queryset': Category.objects.all(),
'template_object_name': 'category'
}, name='cms-categories'),

模型.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 %}

最佳答案

我发现文档有点不清楚,但 use_for_related_fields Manager属性可能是您正在寻找的。尝试时,请注意 this functionality uses _default_manager ,它将始终指向在 Model 类中声明的第一个 Manager,无论它被赋予什么属性名称。您始终可以通过覆盖 queryset 来自定义管理站点中可编辑的项目。适当的方法ModelAdmin而是上课。

做不到...

class Category(models.Model):
def public_stories(self):
return Story.objects.filter(category=self)

...和...
{% for story in category.public_stories %}

这至少避免了重复确定哪些故事是可见的逻辑。

关于模型中 _set 的 Django 管理器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/563367/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com