【问题标题】:Django absolute url not working in html templateDjango绝对网址在html模板中不起作用
【发布时间】:2019-01-07 11:18:32
【问题描述】:

在我发布这个问题之前,我尝试了几种解决方案,但没有 vien,可能是因为我在 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。我希望能够在网站的多个位置包含课程的 url,包括运行文本。

非常感谢您的帮助!

【问题讨论】:

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


    【解决方案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 检索课程(注意:未经测试的代码,因此它可能无法开箱即用 - 但您有一个非常全面的文档可以帮助您) :

    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 的调用(在 python 代码中)或者它是{% url %} 模板标签的兄弟(在模板中)。

    【讨论】:

    • desthuillier,感谢您的热心帮助。我尝试了你的建议,但它仍然显示空白。可能是因为模型具有多对多关系,并且需要不同的解决方案。请提供您的帮助。
    • @Mohammed 这就是为什么你应该在你的问题中发布相关代码 - 这样可以避免浪费每个人的时间......
    • 真的很抱歉。我为此道歉。同时,感谢您的宝贵时间和帮助。
    • 请确保您下次在问题中发布所有相关上下文...所以,我根据您的真实模型编辑了我的答案 - 但如前所述,这是未经测试的代码,可能无法作为是(但它应该让你开始,这就是重点)。
    • 感谢@bruno_desthuilliers 的帮助。我非常感谢你。我实施了第二个解决方案,我发现了反向错误。我最不想面对的是一个反向错误(我是 django 的新手!)。但是,我不得不使用外键将模型从 ManyToMany 修改为一对多。我尝试了你的第一个答案,它就像魔术一样工作。感谢您花时间帮助我。你真是个救世主。非常感谢你。
    猜你喜欢
    • 2012-08-23
    • 1970-01-01
    • 1970-01-01
    • 2014-10-22
    • 2020-01-22
    • 2017-01-02
    • 2019-06-25
    • 2015-03-26
    • 2021-03-07
    相关资源
    最近更新 更多