How to get a parent from a child FK?

Viewed 152

models.py

class Product(models.Model)
 name = models.CharField()

class User(models.Model)
 name = models.CharField()

class List(models.Model)
 user = models.ForeignKey(User)

class Item(models.Model)
 name = models.CharField()
 list = models.ForeignKey(List)
 user = models.ForeignKey(User)
 product = models.ForeignKey(Product)

views.py

class ListView(View)
  def get(self, request, pk)
    list = List.objects.get(id=pk)
    return render(request, "list.html", {"list" : list})

list.html

{% for item in list.item_set.all %}
  {{ item.name }}
  {{ item.user.name }} - ??
  {{ item.product.name }} - ??
{% endfor %}

How get user.name и product.name?

I tried it:

  1. {% item.user_set.first.name %} - does not work

  2. {% for user in item.user_set.all %}{{ user.name }}{% endfor %} - does not work

  3. Model method:

    def get_user(self): 
        self.user_ser.get() #does not work
    

How do I solve this problem?

3 Answers

Since an Item has a ForeignKey to a Product object, you can access the related object with item.product, so you can render this with:

{{ item.product.name }}
{{ item.user.name }}

If you use the standard User module, it is {{ item.user.username }}. It is possible that this is empty, for example if the name of the related user is the empty string ''.

In order to retrieve the elements more efficient however, it might be better to perform a .prefetch_related(..) [Django-doc] to retrieve these items in bulk:

class ListView(View)
  def get(self, request, pk)
    list = List.objects.prefetch_related('item_set', 'item_set__product', 'item_set__user').get(id=pk)
    return render(request, "list.html", {'list' : list})

From user : {{user.items}} # to access to the items objects
From item: {{item.user.name}} # to access to the user name field

class Item(models.Model)
 name = models.CharField()
 list = models.ForeignKey(List)
 user = models.ForeignKey(User, related_name='items')
 product = models.ForeignKey(Product)

It works! My error was that I looked at the field names in the database, not in the file models.py. They are different.

Thank you for your help!

All the answers above are correct!

Related