在 django 中控制请求查看和模板输出

Control requests to view and template output in django

这是获取 EducationalRecord 模型中所有记录的视图:

def all_education_resume(request):
    RESUME_INFO['view'] = 'education'
    educations_resume = EducationalRecord.objects.all().order_by('-created_date')
    template = 'resumes/all_resume.html'
    context = {'educations_resume': educations_resume, 'resume_info': RESUME_INFO}
    return render(request, template, context)

现在,如果我想为其他模型(如工作简历、研究简历等)编写这个视图, 我必须另看一个。 我的问题是:

How can I get a view for all these requests, so first check the URL of the request and then do the relevant query? How can I control URL requests in my views?

我的另一个问题和我的第一个问题完全一样,区别在于:

control view that must render in specific template.In other words,in second question the ratio between the template and the view is instead of the ratio of the view to the url or how to create a template for multiple views (for example, for a variety of database resume resumes, I have a template) and then, depending on which view render, the template output is different.

这两个问题我实现如下:

  1. 我为每个请求写了一个视图!
  2. 在每个视图中,我都设置了RESUME_INFO['view']的值,然后在模板页面中查看并指定了相应的模板。

这两个问题的最佳解法是什么?

How can I get a view for all these requests, so first check the URL of the request and then do the relevant query? How can I control URL requests in my views?

您可以访问 request.path,或者您可以让 url(..) 传递带有 kwargs 的参数,例如保存对模型的引用,但这通常是糟糕的设计。通常,如果您使用不同的模型,您可能还必须对这些不同的东西进行排序、以不同的方式过滤它们、以不同的方式渲染它们等等。如果不是这样,那么这通常表明建模有问题。

然而,您可以使用 class-based views [Django-doc], to remove as much boilerplate as posssible. Your view looks like a ListView [Django-doc],通过使用这样的视图,并在必要时进行修补,我们可以省略大部分“样板”代码:

# app/views.py

from django.views.generic.list import ListView

class MyBaseListView(ListView):
    resume_info = None
    <b>template = 'resumes/all_resume.html'</b>

    def <b>get_context_data</b>(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)
        context['resume_info'] = {'view': self.resume_info}
        return context

在单独的列表视图中,您只需指定 resume_infomodelqueryset 即可使用 'all_resume.html' 模板呈现它,例如:

# app/views.py

# ...

class EducationalResumeView(<b>MyBaseListView</b>):
    <b>queryset = EducationalRecord.objects.order_by('-created_date')</b>
    resume_info = 'education'

class OtherModelView(MyBaseListView):
    <b>model = OtherModel</b>
    resume_info = 'other_info'

所以我们这里可以使用继承,把普通的东西只定义一次,在多个视图中使用。如果我们需要在特定视图中更改某些内容,我们可以在该级别覆盖它。

urls.py 中,您使用 .as_view() method [Django-doc] 定义此类视图。例如:

# app/urls.py

from django.urls import path
from app.views import EducationalResumeView, OtherModelView

urlpatterns = [
    path('education/', EducationalResumeView<b>.as_view()</b>),
    path('other/', OtherModelView<b>.as_view()</b>),
]