将多个 Django 应用程序合并到一个视图中,我做错了什么?
Combining multiple django apps into one view, what am I doing wrong?
我有一个包含多个应用程序的 Django 项目,我需要将它们合并并呈现为一个页面。我有以下代码部分:
我试图与其他观点汇总的观点之一:
class ResourceList(generic.View):
model = Submissions
template_name = 'url_list.html'
def get(self, request, *args, **kwargs):
resources = Submissions.objects.all()
return render_to_string(self.template_name, {'object_list': resources})
我试图用来聚合我的应用程序的视图:
class Index(View):
def get(self, request, *args, **kwars):
renderable = {
'content': ResourceList(),
'login': LoginView() # I don't care about the LoginView at the moment.
}
return render(request, 'index.html', renderable)
url_list.html
{% extends "base.html" %} <!--I've removed this, it did nothing -->
{% block content }
{{ object.url}}
<ul>
{% for resource in object_list %}
<li> {{resource.url}} {{ resource.id }} {{ resource.rating }}</li>
{% endfor %}
</ul>
{% endblock %}
index.html
<head>
<title>HI</title>
</head>
<body>
{% block login %} login {% endblock %} {% block content %} content {% endblock %}
</body>
</html>
问题是当我去测试时它只呈现 "login content" url 我已经为页面设置好了。如果我将 render_to_string
更改为 render_to_response
并转到 url 我已设置为仅渲染该视图,一切正常。这是怎么回事?
我尝试过的事情:
- 从 url_list.html 中删除扩展和块定义不起作用。
- 将
request
传递到 renderable
中的对象实例,我收到 __init__ expects 1 argument, got 2
错误
- 在 ResourceList 上定义
__init__
以接受 request
参数。它只呈现占位符内容。
你不能那样做。视图是美化的功能。
它们有一个由 Django 内部调用的入口点 (dispatch()
),并根据 HTTP 方法(此处为 get()
)调用自身的正确方法。
将视图转换为字符串只会显示其名称,而不是调用它。
如果你想聚合多个视图的行为,你有几种选择。
- 您可以在函数中提取这些行为,并让您的实际视图调用这些函数。
- 你可以创建 mixins,然后将它们混合到视图中。
例如:
from django.views.generic.base import ContextMixin
class ResourceListMixin(ContextMixin):
def get_resource_list(self):
# we put it in a separate method to allow easy overriding
return Submissions.objects.all()
def get_context_data(self, **kwargs):
kwargs['resources'] = self.get_resource_list()
return super(ResourceListMixin, self).get_context_data(**kwargs)
现在您可以将其混合到任何视图中,它会自动知道{{ resources }}
。例如:
from django.views.generic.base import TemplateView
class IndexView(ResourceListMixin, TemplateView):
template_name = 'index.html'
# nothing else here, we leverage the power of Django's
# TemplateView - it will do everything by itself
然后 IndexView
视图将呈现 index.html
模板,并且它能够做到 {% for resource in resources %}
.
我有一个包含多个应用程序的 Django 项目,我需要将它们合并并呈现为一个页面。我有以下代码部分:
我试图与其他观点汇总的观点之一:
class ResourceList(generic.View):
model = Submissions
template_name = 'url_list.html'
def get(self, request, *args, **kwargs):
resources = Submissions.objects.all()
return render_to_string(self.template_name, {'object_list': resources})
我试图用来聚合我的应用程序的视图:
class Index(View):
def get(self, request, *args, **kwars):
renderable = {
'content': ResourceList(),
'login': LoginView() # I don't care about the LoginView at the moment.
}
return render(request, 'index.html', renderable)
url_list.html
{% extends "base.html" %} <!--I've removed this, it did nothing -->
{% block content }
{{ object.url}}
<ul>
{% for resource in object_list %}
<li> {{resource.url}} {{ resource.id }} {{ resource.rating }}</li>
{% endfor %}
</ul>
{% endblock %}
index.html
<head>
<title>HI</title>
</head>
<body>
{% block login %} login {% endblock %} {% block content %} content {% endblock %}
</body>
</html>
问题是当我去测试时它只呈现 "login content" url 我已经为页面设置好了。如果我将 render_to_string
更改为 render_to_response
并转到 url 我已设置为仅渲染该视图,一切正常。这是怎么回事?
我尝试过的事情:
- 从 url_list.html 中删除扩展和块定义不起作用。
- 将
request
传递到renderable
中的对象实例,我收到__init__ expects 1 argument, got 2
错误 - 在 ResourceList 上定义
__init__
以接受request
参数。它只呈现占位符内容。
你不能那样做。视图是美化的功能。
它们有一个由 Django 内部调用的入口点 (dispatch()
),并根据 HTTP 方法(此处为 get()
)调用自身的正确方法。
将视图转换为字符串只会显示其名称,而不是调用它。
如果你想聚合多个视图的行为,你有几种选择。
- 您可以在函数中提取这些行为,并让您的实际视图调用这些函数。
- 你可以创建 mixins,然后将它们混合到视图中。
例如:
from django.views.generic.base import ContextMixin
class ResourceListMixin(ContextMixin):
def get_resource_list(self):
# we put it in a separate method to allow easy overriding
return Submissions.objects.all()
def get_context_data(self, **kwargs):
kwargs['resources'] = self.get_resource_list()
return super(ResourceListMixin, self).get_context_data(**kwargs)
现在您可以将其混合到任何视图中,它会自动知道{{ resources }}
。例如:
from django.views.generic.base import TemplateView
class IndexView(ResourceListMixin, TemplateView):
template_name = 'index.html'
# nothing else here, we leverage the power of Django's
# TemplateView - it will do everything by itself
然后 IndexView
视图将呈现 index.html
模板,并且它能够做到 {% for resource in resources %}
.