djangofilterdjango-filter

django filter two ManyToManyField equal


class VideoUserModel(models.Model):
    user = models.ManyToManyField(get_user_model())
    viewlist = models.ManyToManyField(get_user_model(), related_name='view_list', blank=True, null=True)

I want to get the queryset of user list equal viewlist. How to do this? VideoUserModel.objects.all().filter(user=**viewlist**)


Solution

  • There is no trivial answer to that. We can do this by counting the number of nusers, the number of items in the viewlist relation and the number of items in user that are also in nuser and then check if these three are all equal:

    from django.db.models import Count, F, Q
    
    VideoUserModel.objects.annotate(
        nuser=Count('user', distinct=True),
        nview=Count('viewlist', distinct=True),
        nuserfilter=Count('user', filter=Q(user=F('viewlist')), distinct=True)
    ).filter(
        nuser=F('nview'),
        nview=F('nuserfilter')
    )

    Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to work with the get_user_model() method [Django-doc], since that requires loading the auth app before the current app. For more information you can see the referencing the User model section of the documentation.