我正在尝试为我的应用程序创建一个非常简单的自定义视图。 假设我有一个简单的模型:
class Person(models.Model):
Name = models.CharField(max_length = 255)
pass
class Company(models.Model):
Title = models.CharField(max_length = 255)
pass
我想显示一个对象列表。在一个网址上-人员列表,在另一个网址上-公司列表。因此,我只创建视图:
def PersonListView (request):
_persons = Person.objects.all()
context = {
"object_list": _persons
}
return render (request, "PersonListView.html", context)
def CompanyListView (request):
_companies = Person.objects.all()
context = {
"object_list": _companies
}
return render (request, "CompanyListView.html", context)
然后将路径添加到网址-/人员用于人员列表,//公司用于公司列表。
urlpatterns = [
path('/Person', PersonListView),
path('/Company', CompanyListView)
]
一切正常。但是我已经有一个问题:
为什么我的视图函数有一个 request 变量,但是我可以从url调用此函数而无需定义此变量?
为什么我不能使用这种语法path('/Person', PersonListView())
?这个括号有什么问题?
还有我的问题的另一部分。 但是后来我决定进行一些重构-我打算对个人和公司使用一个视图,因此我必须传递变量 context 来查看功能。而且我基本上知道该怎么做:
def ObjectList (request, _context):
_objects = _context.objects.all()
data = {
"object_list": _objects
}
return render (request, "ListView.html", data)
此处_context-具体类(人员或公司)。
我的问题出在urls.py中,我必须调用ObjectList并传递2个变量:
_context-在这里没有问题,我知道该怎么做
和请求。
在这里我遇到了墙,因为我不知道如何将其传递给我的功能。如果我将其留空,则会出现错误 “ ObjectList()缺少1个必需的位置参数:'request'”
这是回溯:
Internal Server Error: /Entities/Person/
Traceback (most recent call last):
File "D:\Work\Python\virtualenvs\TestProject\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "D:\Work\Python\virtualenvs\TestProject\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "D:\Work\Python\virtualenvs\TestProject\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
TypeError: ObjectList() got multiple values for argument '_context'
[25/Jul/2019 00:25:37] "GET /Entities/Person/ HTTP/1.1" 500 62910
答案 0 :(得分:1)
您的第二个问题回答您的第一个问题。您不会从URL 调用视图; Django在遇到匹配请求时会在内部执行此操作。如果您尝试从那里调用它,则会看到错误消息。
我不明白为什么您认为您需要在第三个问题中传递来自URL的请求。不,这就是问题1和2的重点。
您的URL模式应该捕获视图的参数,或者将它们作为第三个参数传递给path
。因此,在您的情况下,可以使用捕获变量的单个模式:
path('/<str:object_type>/', object_list, name='object_list')
然后:
def object_list(request, object_type):
types = {'Person': models.Person, 'Company': models.Company}
if object_type not in types:
raise Http404
objects = types[object_type].objects.all()
或者,使用两个单独的URL模式并将类型明确地传递为the third parameter:
urlpatterns = [
path('/Person', object_list_view, {'object_type': Person}, name='person_list'),
path('/Company', object_list_view, {'object_type': Company}, name='company_list'),
]
您的视图可以是:
def object_list(request, object_type):
objects = object_type.objects.all()
最后,对于这个非常简单的用例,您应该考虑使用generic list view;那么您根本不需要定义任何视图:
from django.views.generic import ListView
urlpatterns = [
path('/Person', ListView.as_view(model=Person)),
path('/Company', ListView.as_view(model=Company))
]