Reputation: 3046
I am trying to merge the two count queries in the below visible
function into one query.
Function should return True if there are no relations or if there are relations and some specific filtering is true.
class OtherModel(models.Model):
starts = models.DateField()
ends = models.DateField()
class MyModel(models.Model):
m2m = models.ManyToManyField('OtherModel', blank=True, )
def visible(self):
# Should always return True if no relations to OtherModel are present.
if self.m2m.exists():
# If relations to OtherModel are present check for starts and ends.
# The reason for the first check is that if there are no relations
# and the below query returns 0 the function will return False
today = datetime.date.today()
return self.m2m.filter(starts__lte=today, ends__gte=today).exists()
return True
EDIT: More code and comments, replaced count with exists.
The m2m relation is for date restrictions but if no date restrictions are available the function should return True (object visible if no restrictions at all but not visible if restrictions present but not matching current date).
The sample code is just a simplified example, I will need to do this and actually return querysets as well.
Upvotes: 0
Views: 2891
Reputation: 3046
Solved it with Q and aggregate, thanks Aamir for exists():
def visible(self):
today = datetime.date.today()
return MyModel.objects.annotate(num_m2m=Count('m2m')).filter(
Q(pk=self.pk) &
(
Q(m2m__starts__lte=today) &
Q(m2m__ends__gte=today) |
Q(num_m2m=0)
)
).exists()
Upvotes: 3
Reputation: 39669
Not sure exactly what are your actual requirements but I think you want to avoid self.m2m.count() > 0
extra check and wanted to return a boolean value from function if it exists or not, then you need .exists which will return True
if the QuerySet contains any results, and False
if not:
def visible(self):
# return True or False
return self.m2m.filter(some_filter=some_value).exists()
Upvotes: 1