Home > Enterprise >  django - having trouble selecting values based on FK relationship in views.py
django - having trouble selecting values based on FK relationship in views.py

Time:12-05

I have two models that look like;

class Body(models.Model):
    body_id = models.AutoField(primary_key=True)
    is_adult = models.BooleanField(default=False)
    body = models.TextField()
    add_user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    add_date = models.DateTimeField()
    edit_user = models.CharField(max_length=25, blank=True, null=True)
    edit_date = models.DateTimeField(blank=True, null=True)
    category = models.ForeignKey(Category, models.CASCADE)

    class Meta:
        managed = True
        db_table = 'jdb_body'


class BodyTag(models.Model):
    body_tag_id = models.AutoField(primary_key=True)
    body = models.ForeignKey('Body', models.CASCADE)
    tag = models.ForeignKey('Tag', models.CASCADE, db_column='tag')

    class Meta:
        managed = True
        db_table = 'jdb_body_tag'

    def __str__(self):
        return self.tag

I have a view that looks like;

def index(request):
latest_body_list = Body.objects.all().order_by('-body_id')
context = {
    'latest_body_list': latest_body_list
}
return render(request, 'index.html', context)

That view gives me a list Body records no problem. I am trying to display Body records with their corresponding BodyTag records. What am I doing wrong?

CodePudding user response:

You neeed a ManyToManyField in your class Body

tags = models.ManyToManyField('Tag')

To access

body = Body.objects.get(body_id=1)
tags = body.tags.all()

CodePudding user response:

If you mean displaying these in your template, then all you have to do is follow the ForeignKey relationship backwards. This is shown in the documentaion for the views, but it would look pretty much the same in the template. Something like:

{% for body in latest_body_list %}
    {{ body }}
        {% for tag in body.tag_set.all %}
            {{ tag }}
        {% endfor %}
{% endfor %}

The -set is what tells django to look backward in the ForeignKey relationship.

A perhaps better way, also shown in the documentation would be to define a related_name in your ForeignKey:

class BodyTag(models.Model):
    body_tag_id = models.AutoField(primary_key=True)
    body = models.ForeignKey('Body', models.CASCADE, related_name='tags')
    tag = models.ForeignKey('Tag', models.CASCADE, db_column='tag')

Then your template could be written a little better:

{% for body in latest_body_list %}
    {{ body }}
        {% for tag in body.tags.all %}
            {{ tag }}
        {% endfor %}
{% endfor %}
  • Related