Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Distinct values on filtered queryset and 'Q' operator

I have these models:

class Event(models.Model):

    title = models.CharField(max_length=200)
[...]

class dateEvent(models.Model):

    event = models.ForeignKey('Event', on_delete=models.CASCADE)
    start_date_time = models.DateTimeField(auto_now=False, auto_now_add=False)
[...]

and in my views.py I want to create a query which selects an event given specific parameters (start date, etc.). I have no issues with my query:

distinct = Event.objects.values('id').annotate(id_count=Count('id')).filter(id_count=1)
events = Event.objects.filter(Q(dateevent__start_date_time__gte=start_date) & Q(dateevent__start_date_time__lte=end_date))

This pulls up more ideantical results if there is more than one dateevent for each event though, which I don’t want. This is my attempt of getting distinct values, which fails with a 'QuerySet' object has no attribute 'Q' error. what am I missing?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

events = Event.objects.filter(id__in=[item['id'] for item in distinct]).Q(dateevent__start_date_time__lte=end_date).distinct().exclude(type='recording release').order_by('dateevent__start_date_time')

>Solution :

I think you are making this too complicated. You can work with .distinct() [Django-doc]:

Event.objects.filter(
    dateevent__start_date_time__gte=start_date,
    dateevent__start_date_time__lte=end_date
).distinct()

You can not .order_by(..) on the related dateEvents, since then you that will thus be part of the SELECT ... clause, and prevent the uniqness filter from working properly. You can however work with an aggregate over it. For example:

from django.db.models import Min

Event.objects.exclude(type='recording release').filter(
    dateevent__start_date_time__gte=start_date,
    dateevent__start_date_time__lte=end_date
).alias(
    first_event=Min('dateevent__start_date_time')
).order_by('first_event').distinct()
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading