Comparing two lists

43 views
Skip to first unread message

Richard Hall

unread,
Jan 25, 2017, 7:22:55 PM1/25/17
to Django users
Hello, I've only just started with Django and need a bit of help steering myself in the right direction.

I want to create a page that has a list of possible forms that could be filled in for a patient in a medical study and differentiate between those forms which have already been completed and those that have yet to be started. I have 3 tables: 'Building' which contains the list of forms, 'Street' which contains the list of patients and 'Address' which records which form exists for each patient. The relevant bit of models.py looks like this:

class Building(models.Model):
    crf_code = models.CharField(max_length=6, primary_key=True)
    crf_name = models.CharField(max_length=100)

class Street(models.Model):
    village = models.ForeignKey(Village)
    patient_number = models.PositiveIntegerField()
    initials = models.CharField(max_length=3)


class Address(models.Model):
    street = models.ForeignKey(Street, related_name='addresses')
    building = models.ForeignKey(Building, related_name='addresses')
    completed = models.BooleanField(default=False)
 
I've created a view that creates two lists, one of all buildings (i.e. forms that could be entered for a patient) and another of forms already existing, filtered by patient id:

def street2(request, patientid):
    context_dict = {}
    try:
        address = Address.objects.filter(street__pk=patientid)
        crf = Building.objects.all()
        context_dict['address'] = address
        context_dict['crf'] = crf
    except Street.DoesNotExist:
        context_dict['address'] = None
        context_dict['crf'] = None
   
    return render(request, 'trial/street2.html', context_dict)

My problem comes with relating the two lists to each other in my template. what I want to do is list the buildings and then, depending if the form already exists, display an "edit form" or "create form" link:

<div>
    <ul>
        {% for x in address %}
        <li>
            <div>{{ x.building }}</div>
            <div>
                {% if ???? %}
                link to edit form
                {% elif %}
                link to create form
                {% endif %}
            </div>
        </li>
        {% endfor %}
    </ul>
</div>

I'm not sure if I've explained myself clearly; if not I apologize. I'm only just starting out and am floundering a bit. Any help or guidance would be hugely appreciated.

Thank you,

Richard

ludovic coues

unread,
Jan 26, 2017, 3:21:18 AM1/26/17
to django...@googlegroups.com
You are assuming you can have address without building.
{% if x.building %}
> --
> 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/237bb16a-d76e-42b9-bd46-a7b2f9c43f4c%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.



--

Cordialement, Coues Ludovic
+336 148 743 42
Message has been deleted

Richard Hall

unread,
Jan 26, 2017, 4:41:54 AM1/26/17
to Django users
Thanks for replying, I need all the help I can get. What I'm trying to do is the opposite of what I seem to be doing. Rather than looking for an address without a building I am trying to see, from my list of all buildings, which one has an address (filtered by patientid). I can easily list all addresses associated with a building, it is just getting only the ones for a particular patient that I'm stuck with.

Thanks,

Richard

ludovic coues

unread,
Jan 26, 2017, 4:53:10 AM1/26/17
to django...@googlegroups.com
Building.objects.filter(addresses__street__pk=patientid) will return
all buildings with an address in the same street as the patient. If I
understand correctly, that is :)
> --
> 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/0ec5c059-a0b3-41ab-8f42-2603e0d640e5%40googlegroups.com.

Melvyn Sopacua

unread,
Jan 26, 2017, 11:30:28 AM1/26/17
to django...@googlegroups.com

Hello,

 

I don't know if you've changed names to protect the innocent, but conceptually, these models are hard to translate to the real world. This is the opposite of what object oriented programming is trying to accomplish and probably why you're having a hard time figuring it out and explaining to others.

 

For example, it makes no sense that a street has a patient number and initials. Address should be a through model for a ManyToManyField on Building (if we're talking buildings, addresses and streets and ignore patients), but then "completed" isn't a good way to distinguish between "23 Main Road" and "25 Main Road".

 

You get the idea...

 

From the looks of it, you altered your code (street_pk=patientid should not work as you think, as patient_number is not the pk of Street). If you do that - please use an anology that makes sense, possibly using the classics like fruits, books and pizzatoppings.

 

On Wednesday 25 January 2017 15:27:00 Richard Hall wrote:

 

> My problem comes with relating the two lists to each other in my

> template. what I want to do is list the buildings and then, depending

> if the form already exists, display an "edit form" or "create form"

> link:

>

> <div>

> <ul>

> {% for x in address %}

 

But...You're not listing buildings. You're listing addresses. So all buildings that come up, exist.

Figuring out the buildings "owned by" the patient which don't have addresses, you should iterate the buildings and inspect the addresses attribute. For ease of use in template, one could do this:

 

class Building(models.Model):

# ....

@property

def has_address_for_patient(self):

return hasattr(self, 'addresses') and \

self.addresses.filter(street__pk=patientid).count() > 0

 

Remember that Django Template Language strives to keep programming out of the template, so either do the above in your model or in your view when building the context.

--

Melvyn Sopacua

Richard Hall

unread,
Jan 26, 2017, 4:30:35 PM1/26/17
to Django users
Melvyn, thanks for looking at this. Despite my inept attempt at explanation you've understood what I am trying to do - I need to revisit my relationships and fully explore my options at the model level.

Thanks again,

Richard

P.S. I'll try to use clearer analogies in the future - in my head the database is a village which is really obvious, but only if you are in my head!
Reply all
Reply to author
Forward
0 new messages