Simplifying code with multiple loops and logic, into queryset aggregates

15 views
Skip to first unread message

Joel Mathew

unread,
Apr 30, 2019, 10:24:19 AM4/30/19
to django...@googlegroups.com
My models:


class customer(models.Model):
cstid = models.AutoField(primary_key=True, unique=True)
insurance_number = models.CharField(max_length=100, blank=True, null=True)
name = models.CharField(max_length=35)
ageyrs = models.IntegerField(blank=True)

class Admission(models.Model):
id = models.AutoField(primary_key=True, unique=True)
clinic = models.ForeignKey(Clinic, on_delete=models.CASCADE)
customer = models.ForeignKey(customer, on_delete=models.CASCADE)
diagnosis = models.CharField(max_length=2000, default='', blank=True)
date_admission = models.DateTimeField(default=timezone.now)
ward = models.ForeignKey(Ward, on_delete=models.CASCADE)
bed = models.ForeignKey(Bed, on_delete=models.CASCADE)
discharged = models.BooleanField(default=False)
ip_number = models.IntegerField(blank=True)
ip_prefix = models.CharField(max_length=20, default='', blank=True)

My objective: Set a variable to a query filter, adding a property, 'is_admitted' to the queryset, so that I can pass this query set to the template and use the property while displaying data.

Code:


def is_admitted(cust):
admission = Admission.objects.filter(customer=cust, discharged=False)
admission_results = len(admission)
if admission_results > 0:
return True
return False


my_q = or_q_if_truthfull(
cstid=HospitalID,
name__lower__contains=name.lower() if name else None,
ageyrs=ageyrs if ageyrs.isdigit() else None,
agemnths=agemnths if agemnths.isdigit() else None,
mobile__contains=mobile if mobile else None,
alternate__contains=alternate if alternate else None,
email__lower__contains=email.lower() if email else None,
address__lower__contains=address.lower() if address else None,
city__lower__contains=city.lower() if city else None
)
ORSearchResult = customer.objects.filter(my_q, linkedclinic=clinicobj)
cust_set = []
cust_admission_status = []
for cust in ORSearchResult:
cust_set.append(cust)
cust_admission_status.append(is_admitted(cust))
print(f"Customer name: {cust.name} Admission status: {is_admitted(cust)}")
cust_templ_set = zip(cust_set, cust_admission_status)

And in template, I will do:

{% for cust, status in cust_templ_set %}
{{ cust.name }} {{ status }}
{% endfor %}

I want to understand how I can convert my above code by generating an aggregate over the queryset, so that I can use a property of the query, and change the template code to the following, and avoid the loop in the view, and the zip. So that the template code becomes:

{% for cust in customers %}
{{ cust.name }} {{ cust.status }}
{% endfor %}

I am not sure whether I am making complete sense, and can explain further.
Sincerely yours,

 Joel G Mathew

Matthew Pava

unread,
Apr 30, 2019, 11:03:47 AM4/30/19
to django...@googlegroups.com

It was a little difficult to follow your message because the formatting is non-standard, but I think this might be what you’re looking for.

Also, you should try to follow more Python coding conventions: models start with an upper case letter. Variables start with a lower case letter.

 

And you probably want to use a QuerySet Manager on Customer. Maybe a query like this:

Customer.objects.annotate(is_admitted=Case(When(admission_set__discharged=False, then=True), default=False).distinct()

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CAA%3Diw_-8OUE5cd%3DZBahkLMTSTD%3DOXJbYenHjiB3ORGfkY9mSrQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Joel Mathew

unread,
Apr 30, 2019, 11:49:14 AM4/30/19
to django...@googlegroups.com
Thank you Matthew. Excellent advise as always. When I started off with this project 5 months ago, I was a beginner to both django and python. I've come a bit along the journey. That customer model is the first model I created, and I was unaware of these conventions. By the time I realized that, the project has branched into several apps, and the code now runs into thousands of lines of code. I didnt change the naming due to fear of breaking other code. :)

Nowadays I do it more "pythonically". Still, it's great to have people like you offer excellent general advise to help budding enthusiasts!

Sincerely yours,

 Joel G Mathew


Reply all
Reply to author
Forward
0 new messages