简体   繁体   中英

Django filtering on related models attributes

class Count(models.Model):
    start_time = models.DateTimeField(null = True, blank = True)
    end_time = models.DateTimeField(null = True, blank = True)

class AccessRecord(models.Model):
    user = models.ForeignKey(get_user_model(), related_name = 'accesses', on_delete = models.CASCADE)
    count = models.ForeignKey(Count, related_name = 'accesses', on_delete = models.CASCADE)

With this model scheme, how can i filter on a Count queryset based on the user?

For example, i want every count object that has the first Access Record with a certain user id.

user_id = 2
all_counts = Count.objects.all()
list(filter(lambda x: x.accesses.first().user.pk == user_id, all_counts))

^^ This would work. However i get a list instead of a query set (i still need to order_by, etc..)

What's the best alternative here?

Edit. Every Count is guaranteed to have at least one Access Record.

You can also use accesses as within a filter.

Thus Count.objects.filter(accesses__user_id=2)

But this will retrieve all Count's for this use, not just the ones for each first AccessRecord.

Thus by adding an order by you can do something like

first_acccess_count = Count.objects.filter(accesses__user_id=2).order_by('start_time').first()

Note: first_acccess_count can be None, if user had no access yet.

Edit: Question was unclear, query should do: I want every count object of that user_id. But the user needs to have the first Access Record.

from django.db.models import Max
# First retrieve all first created AccessRecord's, by grouping on 
# Count and to find all lowest ids of AccessRecords. As lower id 
# can be seen as created first.
all_first_records_qs = AccessRecord.objects.values_list('count_id') \
    .annotate(max_id=Min('id')).values_list('max_id', flat=True)
# values_list returns a QuerySet, and thus lazy, which allows it to 
# be used as a subquery
all_counts = Count.objects.filter(
    accesses__user_id=2,
    accesses__id__in=all_first_records_qs,
)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM