Get Data From Three Tables (JOIN)

Question:

We have three Models as below.

class Category(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(max_length=200)

class CategoryManager(models.Model):
    category = models.ForeignKey(Category, on_delete=models.PROTECT, verbose_name=_('Course Category'), related_name="category_categorymanager")
    manager = models.ForeignKey(_user, verbose_name=_('Category Manager'), on_delete=models.CASCADE, related_name="user_categorymanager")

class Course(models.Model):   
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(max_length=200, verbose_name=_('Course Name'))
    ...
    price = models.DecimalField(max_digits=7, decimal_places=2, verbose_name=_('Course Price'), blank=True, null=True)
    slug = models.SlugField(unique=True, blank=True)
    category = models.ForeignKey(Category, related_name='courses_category', on_delete=models.PROTECT)

We want to filter courses by the CategoryManager.

@admin.register(Course)
class CourseAdmin(admin.ModelAdmin):
    def get_queryset(self, request):
        category_manager_list=CategoryManager.objects.filter(manager=request.user)
        ... 
        return ....

Using the category_manager_list obtained like above, we want to list all courses belonging to these categories.

Asked By: fdas

||

Answers:

You can filter with:

@admin.register(Course)
class CourseAdmin(admin.ModelAdmin):
    def get_queryset(self, request):
        return Course.objects.filter(
            category__category_categorymanager__manager=request.user
        ).distinct()

Note: Your CategoryManager model acts as a junction table for a many-to-many relation between Category and _user. You can span a
ManyToManyField [Django-doc]
on the Category model with:

class Category(models.Model):
    # …
    managers = models.ManyToManyField(
        _user,
        through='CategoryManager'
    )

Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.

Answered By: Willem Van Onsem
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.