Search code examples
djangourlprimary-keyslug

Connecting Foreign Key to URL in Django


I'm creating an online courses website, in which you create a course object and add chapter objects to it. Each chapter has a foreign key to a course object:

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})

my view is like this:

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)

And here is the url path:

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

And here is the anchor tag:

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

I'm getting the error:

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

Which shows that the URL is found, but I don't get why it doesn't just work.


Solution

  • In your chapter_view you are trying to access directly the field of course. You must use the course.

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

    Is also confusing use a variable like cpk because I don't understand if you refer to a pk field in Course or a pack field in Course.