Django绝对URL在HTML模板中不起作用

时间:2019-01-07 11:18:33

标签: python-3.x url django-views breadcrumbs django-2.1

在我发布此问题之前,我尝试了几种解决方案,但没有成功,可能是因为我在django和Web开发方面经验不足。 我想在导航导航菜单中显示课程名称。但是,它显示空白。使用Django 2.1.4,模型如下:

class Course(model.Model):
    title = models.CharField(max_length=128)
    description = RichTextUploadingField(default='No description available.')

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('course-detail', kwargs={'pk': self.pk})

编辑:添加课程模型

课程模型与课程有很多关系。如下:

class Lesson(models.Model):
    title = models.CharField(max_length=512)
    content = RichTextUploadingField()
    course = models.ManyToManyField(Course)

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('lesson-detail', kwargs={'pk': self.pk})

views.py包含以下视图

class CourseListView(ListView):
    model = Course
    template_name = 'courses/courses.html'
    context_object_name = 'courses'
    paginate_by = 10


class CourseDetailView(DetailView):
    model = Course
    template_name = 'courses/course-detail.html'

class LessonDetailView(DetailView):
    model = Lesson
    template_name = 'courses/lesson-details.html'

urlpatterns包括以下内容:

path('', CourseListView.as_view(), name = 'course-list'),

path('course/<int:pk>/', CourseDetailView.as_view(), name = 'course-detail'),

path('lesson/<int:pk>/', LessonDetailView.as_view(), name = 'lesson-detail'),

lesson-detail的html模板中,包含以下面包屑修饰语:

<!-- ##### Breadcumb Area Start ##### -->
<div class="breadcumb-area">
    <!-- Breadcumb -->
    <nav aria-label="breadcrumb">
        <ol class="breadcrumb">
            <li class="breadcrumb-item"><a href="{% url 'home' %}">Home</a></li>
            <li class="breadcrumb-item"><a href="{% url 'course-list' %}">Courses</a></li>
            <li class="breadcrumb-item"><a href="{{ course.get_absolute_url }}">{{course.title}}</a></li> {% comment%} This doesn't work {%endcomment%}
            <li class="breadcrumb-item active" aria-current="page">{{ lesson.title }}</li>
            <li></li>
        </ol>
    </nav>
</div>

我如何使其起作用?课程标题为“音乐”,所需的输出类似于HOME / COURSES / MUSIC / FLUTE。我希望能够在网站的多个位置包含课程的网址,包括运行文本。

非常感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

LessonDetailView没有任何超能力,它无法猜测您想在模板上下文中拥有一个Course实例,也不希望您想要哪个实例。结果,模板无法解析名称course并确实吐出一个空字符串。

好消息是-假设您的Lesson模型(您忘记发布)在Course上具有ForeignKey,即:

class Lesson(models.Model):
    course = models.ForeignKey(Course, ....)
    # etc

然后您可以从lesson实例中获取相关的课程实例,即:

<li class="breadcrumb-item">
  {% with course=lesson.course %}
  <a href="{{ course.get_absolute_url }}">{{course.title}}</a></li>
  {% endwith %}
</li> 

编辑:

  

可能是因为该模型具有多对多关系,并且需要不同的解决方案

是的,的确如此。并且在开始任何实施细节之前,仅问自己一个问题,如果您仅具有课程ID,如何知道应该选择哪个相关课程?答:不能。 IOW,您必须使课程ID成为课程视图的url模式的一部分:

path('lesson/<int:course_id>/<int:pk>/', LessonDetailView.as_view(), name = 'lesson-detail'),

然后更新视图,以便获取课程ID,从数据库和inject it in the context中检索课程(nb:未经测试的代码,因此可能无法立即使用-但是您有非常全面的文档可为您提供帮助您):

class LessonDetailView(DetailView):
    model = Lesson
    template_name = 'courses/lesson-details.html'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        course = self.object.courses.get(pk=kwargs["course_id"])
        context["course"] = course
        return context

当然还要将模板重置为其初始版本。

编辑2:

我忘了这会破坏Lesson.get_absolute_url(),因为您依赖于了解当前的课程,而在这种情况下这是不可能的。解决方案非常简单,就是从Lesson模型中删除此方法(实际上,模型不应该了解有关url的信息),并将对lesson.get_absolute_url()的所有调用替换为对django.core.urlresolvers.reverse的调用(或使用{% url %} templatetag(在模板中)。