Tuesday, April 30, 2019

RE: Simplifying code with multiple loops and logic, into queryset aggregates

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()

 

 

From: django-users@googlegroups.com [mailto:django-users@googlegroups.com] On Behalf Of Joel Mathew
Sent: Tuesday, April 30, 2019 9:22 AM
To: django-users@googlegroups.com
Subject: Simplifying code with multiple loops and logic, into queryset aggregates

 

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

 

--
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+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@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.

No comments:

Post a Comment