4

I'm working on a Django project and attempting to create some linked models for my data which In think is working, but I cannot seem to work out how to access the linked data.

class One(models.Model)
  name = models.CharField(max_length=50)
  list = models.ArrayField(models.CharField(max_length=50), blank=True)

  def __str__(self): 
    return self.name

class Many(models.Model)
  name = models.CharField(max_length=50)

  related = models.ForeignKey(One, null=True, blank=True)

  def __str__(self): 
    return self.name    

This is the general relationship I have set up.

What I am trying to do is, in a template have access to a list of all 'Ones', and via each of those, can access each Many and it's related attributes. I can see how to access the attributes for a single 'One', but not how to pass all of them and their related 'Many' models and the related attributes for each. Essentially the output I'd like would have a drop down list with the One's, and when this is submitted some Javascript will use the list in the 'Many' model to do some stuff.

Any advice would be much appreciated.

Nowandthen98
  • 300
  • 1
  • 3
  • 13
  • Are you trying to update the UI using ajax calls i.e. populates options in a second dropdown based on the selection in first dropdown? – AKS Apr 03 '17 at 14:34
  • No, I'm actually using OpenLayers, so the list will actually be of country names that will be highlighted on a map – Nowandthen98 Apr 03 '17 at 14:35

3 Answers3

6

If you already have the objects of One model class, you can access the many objects using many_set (refer: backward relations):

{% for one_obj in one_objs %}
    {% for m_obj in one_obj.many_set.all %}
        # do stuff with m_obj here
    {% endfor %}
{% endfor %}

One important thing to note here is that this will execute a db query for each m_obj. To make this efficient, you could prefetch the many_set with one_objs in your view.

In your view, use prefetch_related:

one_objs = One.objects.all().prefetch_related('many_set')
AKS
  • 18,983
  • 3
  • 43
  • 54
2

You can use Django's "prefetch_related" and Django's "related_name".

Also, this question has been answered here.

Though, here is what you might want, first, change your foreign key definition to this :

related = models.ForeignKey(One, null=True, blank=True, related_name='relateds')

Then you can reverse-fetch the foreign keys:

one = One.objects.get(name="TheOneYouWant").prefetch_related('relateds')
manys = one.relateds
Community
  • 1
  • 1
Qrom
  • 487
  • 5
  • 20
1

Reverse lookups are accessible through an object's ___set attribte. So to get all the "Many" objects for a given "One" you could do one.many_set

Django reverse lookup of foreign keys

Regarding usage in a template, sets are accessible by adding "all" (since the set returns a queryset, you can run queries against it, including in the template)

Access ForeignKey set directly in template in Django

See the relevant section of the Django Documentation: https://docs.djangoproject.com/en/dev/topics/db/queries/#following-relationships-backward

Community
  • 1
  • 1
Robert Townley
  • 3,414
  • 3
  • 28
  • 54