如何正确地将多个参数(从模板/上下文)传递到Django中的视图?

时间:2018-09-27 21:24:45

标签: django templates view arguments

我对Django(v = 2.1)比较陌生。由于几天来一直在寻找解决这个问题的方法,我感到很困惑,我认为这很容易,但是,尽管在这里和其他地方读了很多文章,但仍未能解决。 我有两个模型:教师和作业。非常简化:

models.py    

class Teacher(models.Model):
    name = models.CharField(max_length=200)

class Assignment(models.Model):
    title = models.CharField(max_length=200)
    teacher = models.ForeignKey(Teacher, on_delete=models.SET_NULL, null=True)

我有一个(工作中)网站,其中列出了nr教师的作业。我使用通用的DetailView函数生成的x,其中一些代码如下所示:

assignments_list.html

{% for assignment in teacher.assignment_set.all %}
    ...
    <a href="{% url 'assignment-detail' pk1=assignment.teacher.pk pk2=assignment.pk %}">{{assignment.title}}</a>
    ...
{% endfor %}

当我单击assignment.title时,我想获得该特定老师的作业的详细信息页面。 我使用以下网址配置文件:

urls.py

urlpatterns += [path('teacher/<int:pk1>/assignment/<int:pk2>/', views.AssignmentDetailView.as_view(), name = 'assignment-detail')]

并且我使用此视图功能(我尝试了几种变体):

views.py

from .models import Teacher, Assignment
from django.views import generic

class AssignmentDetailView(generic.DetailView):
    model = Assignment
    template_name = 'assignment_detail.html'

    def get_queryset(self, **kwargs):
        queryset = super(AssignmentDetailView, self).get_queryset()
        return queryset.filter(teacher_id=self.kwargs['pk1'], pk=self.kwargs['pk2'])

我正在尝试传递页面上下文(包含任务列表)中的两个参数(pk1和pk2)。 如果单击链接(assignment.title),我的确会看到一个带有pk1和pk2正确数字的URL(我在URL地址栏中看到了该数字,例如http://localhost:8000/teacher/2/assignment/4)。但是没有页面显示。通过调整一些东西,我得到了不同的错误:

  • 语法错误,缺少参数的问题...到目前为止已解决。
  • “查询集未检索到任何对象”(或类似的措辞)。
  • 当前错误:“视图app.views.AssignmentDetailView没有返回HttpResponse对象。它返回None。'

我的问题:

  1. 我在做什么错?我通过正确吗?还是问题在 我的观点?...如何传递参数(老师pk和作业pk) 从模板(或简单地说,上下文?)到视图功能?和 如何使用它们从我的模型中返回正确的对象?
  2. 每次调用视图函数时是否必须传递参数? 参数自动从一个视图(模板)传递到另一视图(模板)?
  3. 最初,我将通过URL传递参数,但稍后我想不通过URL传递参数:我是否仍可以使用模板 参数,但仅在视图中使用它们(而不在url中使用)?这是 要走的路?

非常感谢您的任何建议。

2 个答案:

答案 0 :(得分:0)

您的视图仅返回查询集,而不返回实际对象(详细视图需要该对象)。 如果您只是想获取作业对象,则无需传递教师ID。在您的第一页上,列出单个教师的所有作业,您只需要将Assignment.pk传递到详细信息视图。

path('assignment/<int:pk>/', views.AssignmentDetailView.as_view(), name='assignment-detail')

如果您像上面那样创建URL,则详细信息视图将通过pk处理对象。 如果您想在网址中添加老师ID,您仍然可以这样做,但可以将其命名为<int:teacher_id>。默认情况下,detailview仅在kwarg中查找“ pk”,因此请忽略Teacher_id

答案 1 :(得分:0)

非常感谢您的快速回复(我没想到!)很抱歉,如果我不对所有评论都做出回应,但我会感谢您的帮助。

我再次对其进行了研究,现在了解到queryset返回一个集合而不是一个模型实例(对此,我最好使用“ get”)。我进行了如下更改,现在可以正常工作了:

assignments_list.html

<a href="{% url 'assignment-detail' pk=assignment.teacher.pk pk1=assignment.pk %}">


views.py

class AssignmentDetailView(generic.DetailView):
    model = Assignment
    template_name = 'assignment_detail.html'

def get_object(self, **kwargs):
    assignment = Assignment.objects.get(id=self.kwargs['pk1'])
    return assignment

def get_context_data(self, **kwargs):
    context = super(AssignmentDetailView, self).get_context_data(**kwargs)
    context['teacher'] = Teacher.objects.get(id=self.kwargs['pk'])
    return context

现在可以使用了。我需要两个pk编号,因为'assignment_detail.html'上的标头是包含{% include 'header-teacher.html' %}的{​​{1}}。现在,我从网址中传递了两个值:pk1用于检索正确的作业,pk来提供(额外)正确的上下文(传递教师pk)。