gpt4 book ai didi

python - 重构Django基于类的 View ,清理18个重复类。

转载 作者:太空狗 更新时间:2023-10-30 02:20:16 25 4
gpt4 key购买 nike

https://github.com/AnthonyBRoberts/fcclincoln/blob/master/apps/story/views.py

我有点不好意思承认这是我的。但它是。

class FrontpageView(DetailView):
template_name = "welcome_content.html"
def get_object(self):
return get_object_or_404(Article, slug="front-page")
def get_context_data(self, **kwargs):
context = super(FrontpageView, self).get_context_data(**kwargs)
context['slug'] = "front-page"
events = Article.objects.filter(slug="events")
context['events'] = events
return context

所以这是 Django 中一个非常普通的基于类的详细 View 。

它正在分配一个模板,获取一个 Article 对象,并向 context_data 添加一些内容。

然后这门课我抄了17遍。每次,都会有一个不同的模板,一个不同的 slug,以及添加到 context_data 的不同内容。

想法是,有一个所见即所得的编辑器供管理员更改 Web 内容,还有一个用户身份验证系统,允许多人访问网站内容。基本上,一个 super 简单的 CMS,因此没有人需要编辑 html 来更新网站。

但我真的希望我可以重构它,这样我就没有这些几乎相同的 18 个类。非常欢迎任何关于我应该从哪里开始的建议。

最佳答案

将所有类压缩为一个继承自 TemplateResponseMixin 的类, 作为 DetailView会,(也请查看 SingleObjectTemplateResponseMixin )并覆盖其 get_template_names() 方法以返回适合当前情况的模板。

django-blog-zinnia 中使用了一个很好的例子。项目

def get_template_names(self):
"""
Return a list of template names to be used for the view.
"""
model_type = self.get_model_type()
model_name = self.get_model_name()

templates = [
'zinnia/%s/%s/entry_list.html' % (model_type, model_name),
'zinnia/%s/%s_entry_list.html' % (model_type, model_name),
'zinnia/%s/entry_list.html' % model_type,
'zinnia/entry_list.html']

if self.template_name is not None:
templates.insert(0, self.template_name)

return templates

Django 将获取该名称列表并尝试每个项目以查看它是否存在于模板文件夹中。如果是,则使用该模板。

更新

仔细查看您的代码后,可能是这样的:

在你的主 urls.py 中

# convert each url
url(r'^$', FrontpageView.as_view()),
url(r'^history/$', HistoryView.as_view()),
url(r'^calendar/$', CalendarView.as_view()),
url(r'^news/$', NewsView.as_view()),
url(r'^visitors/$', VisitorsView.as_view()),
...
# to just
url(r'^(?P<slug>[\w\d/-]+)/$', SuperSpecialAwesomeView.as_view()),
# but, put this at the end of urls list after any routes that don't use this view

DetailView,在设置类属性 model 后,将检查 slug 是否在 url 的 kwargs 中,如果是,则它将使用 slug 进行模型查找,就像您已经在做的那样:Article.ojects.get(slug=self.kwargs['slug'])

模型.py

您可以将 type 字段添加到您的 Article 模型。该类型将指定它是什么类型的文章。例如,您的 ChildrenViewYouthViewAdultView 都可以有一种类型的 music(因为模板是所有音乐,我假设这就是它们之间的关系)。

ARTICLE_TYPE_CHOICES = (
(0, 'music'),
(1, 'weddings'),
(2, 'outreach'),
...
)

class Article(models.Model):
...
type = models.IntegerField(choices=ARTICLE_TYPE_CHOICES)
...

然后,在你的 views.py 中

class SuperSpecialAwesomeView(DetailView):
template_name = None
model = Article
def get_template_names(self):
slug = self.kwargs.get('slug', '')
templates = [
# create a template based on just the slug
'{0}.html'.format(slug),
# create a template based on the model's type
'{0}.html'.format(self.object.get_type_display()),
]
# Allow for template_name overrides in subclasses
if self.template_name is not None:
templates.insert(0, self.template_name)

return templates

给定一个类型为 music 的文章实例和一个 ministry/children 的 slug,Django 将寻找一个名为 ministry/children.html< 的模板 和一个名为 music.html 的模板。

如果你需要为其他 View 做一些特殊的事情(比如你可能需要为 SermonsView),那么子类化 SuperSpecialAwesomeView

class SermonsView(SuperSpecialAwesomeView):
paginate_by = 2
queryset = Article.objects.order_by('-publish_date')

关于python - 重构Django基于类的 View ,清理18个重复类。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24270399/

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