Laurence
Laurence

Reputation: 671

Django reverse lookup of a OneToOneField from a ManyToManyField

I'm trying to access specific fields via a rather convoluted lookup in Django. I want to search a ManyToManyField Tags, which links to a Poem model, which in turn is linked to by a UserPoem model with a OneToOneField. I just can't work out how to do it:

class Poem(models.Model):
    title = models.CharField(max_length=256)
    thetext = models.TextField()

class UserPoem(models.Model):
    poem = models.OneToOneField(Poem, related_name='u_poem')
    date = models.DateField()
    user = models.ForeignKey(User)

class Tag(models.Model):
    name = models.CharField(max_length=64, unique=True)
    poems = models.ManyToManyField(Poem)`

So given a tag, I want to get information involving the text of title of the poems in that tag and also the user, date of the poem etc. I've tried various methods involving select_related, but just can't crack it. Here is the (not working) tags request:

def tag_page(request, tag_name):
    tag = get_object_or_404(Tag, name=tag_name)
    poems = tag.poems.order_by('-id').select_related('u_poem')

I'm just really confused by the way that Django's relationships work. I've had untold problems every since I decided to split the Poems table model in two.

This doesn't return an error; it just doesn't seem to return any information from the UserPoem / u_poem table.

Upvotes: 0

Views: 1263

Answers (1)

Armance
Armance

Reputation: 5390

In your place I would do :

class Tag(models.Model):
    name = models.CharField(max_length=64, unique=True)

class Poem(models.Model):
    title = models.CharField(max_length=256)
    thetext = models.TextField()
    tags   = models.ManyToManyField(Poem)

so :

def tag_page(request, tag_name):
    poems_sets = []
    tag = get_object_or_404(Tag, name=tag_name)
    poems = Poem.objects.filter(tags__name=tag).order_by('-id')             
    for p in poems:                
        usersp = UserPoem.objects.filter(poem=p)
        for u in usersp:
            poems_sets.append((p, u))
    return locals() 

template :

{% for poem,usersp in poems_sets %}
    {{poem.title}}
    {{poem.thetext}}
    {% for u in usersp %}
        {{u.date}}
        {{u.user}}
    {% endfor %}
{% endfor %}               

Upvotes: 1

Related Questions