在 Django 中将外键连接到 URL

Connecting Foreign Key to URL in Django

我正在创建一个在线课程网站,您可以在其中创建一个课程对象并向其添加章节对象。每章都有一个课程对象的外键:

class Course(models.Model):
    title = models.CharField(max_length=140, null=False)
    description = models.TextField(null=False)
    cover = models.ImageField(null=False)
    slug = models.SlugField(max_length=100, blank=True)
    pack = models.ForeignKey(CoursePack, on_delete=models.SET_NULL, null=True, blank=True) 
    tag = models.ForeignKey(CourseGroup, on_delete=models.SET_NULL, null=True, blank=True)

    def __str__(self):
        return self.title

    def save(self, *args, **kwargs):
        if not self.id:
            self.slug = slugify(self.title)
        super(Course, self).save(*args, **kwargs)

    def get_absolute_url(self):
        return reverse("course_detail", kwargs={'pk':self.pk,'slug': self.slug})

    signals.pre_save.connect(instance_pre_save, sender="course.Course")

class Chapter(models.Model):
    title = models.CharField(max_length=140, null=False)
    text = RichTextUploadingField()
    slug = models.SlugField(max_length=100, blank=True)
    course = models.ForeignKey(Course, on_delete=models.CASCADE, null=False, blank=False) 

    def __str__(self):
        return self.title

    def save(self, *args, **kwargs):
        if not self.id:
            self.slug = slugify(self.title)
        super(Chapter, self).save(*args, **kwargs)

    def get_absolute_url(self):
        return reverse("chapter_detail", kwargs={'pk':self.pk,'slug': self.slug,
                                                 "cpk":self.course.pk, "cslug":self.course.slug})

我的看法是这样的:

def chapter_view(request, pk, slug, cpk, cslug):
    context = {}

    chapter = Chapter.objects.get(pk=pk, slug=slug, cpk=cpk, cslug=cslug)

    context["chapter"] = chapter

    return render(request, "courses/chapter_detail.html", context)

这里是 url 路径:

re_path(r'^(?P<cslug>[-\w]+),(?P<cpk>\d+)/(?P<slug>[-\w]+),(?P<pk>\d+)/$', chapter_view, name='chapter'),

这里是锚标签:

<a href="{% url 'chapter' slug=chapter.slug cslug=chapter.cslug pk=chapter.pk cpk=chapter.cpk %}" >{{ chapter }}</a>

我遇到错误:

FieldError at /cursos/name-of-the-course,course-pk-integer/name-of-the-chapter,chapter-pk/

Cannot resolve keyword 'cpk' into field. Choices are: course, course_id, id, slug, text, title

这表明 URL 已找到,但我不明白为什么它不起作用。

在您的 chapter_view 中,您当然正在尝试直接访问该字段。您必须使用该课程。

Chapter.objects.get(pk=pk, slug=slug, course__pack=cpk, course__slug=cslug)

使用像 cpk 这样的变量也会造成混淆,因为我不明白你是指 Course 中的 pk 字段还是 Course 中的 pack 字段。

.get() 方法接受参数及其字段名称或相关字段。

在您的 Chapter 模型中,没有名为 cpk 的 attribute/fields,因此 Django 无法将该键解析为字段名称。这就是引发异常的原因。

在您的例子中,参数 cpkcslug 是 non-field 引用,因此它应该替换或重命名为某些实际属性。所以应该是这样

def chapter_view(request, pk, slug, cpk, cslug):
    context = {}

    chapter = Chapter.objects.get(pk=pk, slug=slug, course__pack=cpk, course__slug=cslug)

    context["chapter"] = chapter

    return render(request, "courses/chapter_detail.html", context)

阅读 this official doc 了解有关 django orm 查询的更多信息。