'ManyRelatedManager' object has no attribute - Django

Viewed 529

Very new to Django - I apologise in advance for the poor description!

I have two django models:

class Suite(models.Model):
    slug = models.SlugField()
    client_name = models.ForeignKey(Client, blank=True, null=True, on_delete=models.CASCADE)
    title = models.CharField(max_length=120)

def __str__(self):
    return self.title

def get_absolute_url(self):
    return reverse('courses:detail', kwargs={'slug': self.slug})

@property
def lessons(self):
    return self.portfolioupdate_set.all().order_by('position')


class PortfolioUpdate(models.Model):
    slug = models.SlugField()
    title = models.CharField(max_length=120)
    suite = models.ForeignKey(Suite, on_delete=models.SET_NULL, null=True)
    # suite = models.ManyToManyField(Suite)
    position = models.IntegerField()
    video_url = models.CharField(max_length=200)
    thumbnail = models.ImageField()

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('courses:lesson-detail',
                       kwargs={
                           'course_slug': self.suite.slug,
                           'lesson_slug': self.slug
                       })

I am rendering the list of Portfolio Updates in the following way:

class PortfolioUpdateListView(LoginRequiredMixin, ListView):
    def get(self, request, course_slug, *args, **kwargs):
        user = self.request.user
        suite = get_object_or_404(Suite, adviser__user=user, slug=course_slug)
        context = {'object': suite}
        return render(request, "courses/lesson_list.html", context)

I would like to have the 'suite' field, as a ManyToManyField, rather than a ForeignKey, so that a portfolio update can relate to many suites, rather than a portfolio update relating to a single suite. When I change this in models, and try to render the page, I get 'ManyRelatedManager' object has no attribute 'slug'.

Is what I have described possible, and if so how would I render this? Thanks very much in advance.

1 Answers

I would like to have the 'suite' field, as a ManyToManyField, rather than a ForeignKey, so that a portfolio update can relate to many suites, rather than a portfolio update relating to a single suite. When I change this in models, and try to render the page, I get 'ManyRelatedManager' object has no attribute 'slug'.

This is due to your get_absolute_url method:

def get_absolute_url(self):
    return reverse(
        'courses:lesson-detail',
        kwargs={
            #  .slug for .suite?  ↓
            'course_slug': self.suite.slug,
            'lesson_slug': self.slug
        }
    )

Indeed, if you change suite to a ManyToManyField, then that means that a PortfolioUpdate links to zero, one or more Suites. But you can not get the .slug of a collection of Suites, since there can be zero Suites, or multiple ones where the Suites will have all different slugs.

Likely the best way to fix this is to remove the course_slug from the URL pattern and thus from the reverse call as well.

Related