基于 Django 类的“method_splitter” - 分别传递 2 个 slug 作为模型名称和字段值

Posted

技术标签:

【中文标题】基于 Django 类的“method_splitter” - 分别传递 2 个 slug 作为模型名称和字段值【英文标题】:Django class-based "method_splitter" - passing 2 slugs as model name and field value, respectively 【发布时间】:2013-03-18 17:19:15 【问题描述】:

我想使用基于类的视图创建一个 "method_splitter" 等效项,以删除我的 URL 配置中的一些硬编码。

我想要以下网址:

ListView: http://mysite.com/<model_name>/
DetailView: http://mysite.com/<model_name>/<field_value>/

ListView 的查询位置:

<model_name>.objects.all()

DetailView 的查询集将是:

<model_name>.objects.get(<field>=<field_Value>)

目前,由于 url conf 中的一些硬编码,我的视图有效,但我想找到一个可以扩展的优雅解决方案。

我的解决方案没有给出 404,但什么也不显示:

views.py

class ListOrDetailView(View):

def __init__(self, **kwargs):
    for key, value in kwargs.iteritems():
        setattr(self, key, value)

try: #If/Else instead?
    def goToDetailView(self, **kwargs):
        m = get_list_or_404(self.kwargs['model']) #Is this even needed?
        return DetailView(model=self.kwargs['model'], slug=self.kwargs['slug'], template_name='detail.html', context_object_name='object')

except: #If/Else instead?
    def goToListView(self, **kwargs):
        q = get_object_or_404(self.kwargs['model'], slug=self.kwargs['slug']) #Is this even needed?
        return ListView(model=self.kwargs['model'], template_name='list.html', context_object_name='object_list',) 

MyApp 的 urls.py

url(r'^(?P<model>[\w]+)/?(?P<slug>[-_\w]+)/$', ListOrDetailView.as_view()),

【问题讨论】:

我会将这个视图分成两个视图。在我看来,这是糟糕的设计。这种紧密联系有原因吗? 我愿意将其拆分。您能否发布一个如何将 slug 传递给 ListView/DetailView 的示例?我可以测试它并接受它是否有效。 您打算如何限制人们可以访问的模型?任何人都可以通过任何领域查找任何模型吗? @Thomas - 这是一个很好的观点。在可管理的应用程序中,仅在 urlconf 中进行限制可能是值得的。你会怎么做? 【参考方案1】:

正如聚光灯所说,这是一种可怕的设计模式; Django 的重点是模型和视图的分离。如果您担心可能不得不编写大量重复代码来覆盖所有不同的模型,请相信我,这对于基于类的视图来说不是什么大问题。本质上,您需要为您希望公开的每个模型编写以下代码:

网址.py:

urlpatterns = patterns('',
    url(r'^my_model/$', MyModelListView.as_view(), name="mymodel_list"),
    url(r'^my_model/(?P<field_value>\w+)/$', MyModelDetailView.as_view(), name="mymodel_detail"),
)

views.py:

from django.views.generic import ListView, DetailView

class MyModelListView(ListView):
    model = MyModel


class MyModelDetailView(DetailView):
    model = MyModel

    def get_queryset(self):
        field_value = self.kwargs.get("field_value")
        return self.model.objects.filter(field=field_value)

【讨论】:

以上是关于基于 Django 类的“method_splitter” - 分别传递 2 个 slug 作为模型名称和字段值的主要内容,如果未能解决你的问题,请参考以下文章

Django 基于类的 DeleteView 示例

Django 基于类的视图:覆盖表单名称

Django:基于类的视图无法呈现清晰的表单

Django:在基于类的视图中包含媒体(css/js)

django 基于类的视图是不是继承 method_decorators?

使用基于类的视图和 ajax 的 Django 应用程序?