karanece
karanece

Reputation: 125

Accessing related objects in Django

I have the below model

class Question(db.Model):
    userid = db.CharField(max_length=50)
    posted = db.DateTimeField(auto_now=True)
    question = db.TextField(max_length=500)
    qid = db.AutoField(primary_key=True)
    title = db.TextField(max_length=80)

class Question_tags(db.Model):
    tag = db.ForeignKey('Tags')
    ques = db.ForeignKey('Question')

class Tags(db.Model):
    tid = db.AutoField(primary_key=True)
    tagname = db.CharField(max_length=30)
    tag_cnt = db.IntegerField()

I need to join the 3 models namely Question, Tags and Question_tags and get the below fields question, title, tagname and tag_cnt. I tried with select_related(), but I am getting error like "queryset doesn't contain the object select_related"... Any idea on how to proceed??

Upvotes: 0

Views: 4487

Answers (2)

Gabi Purcaru
Gabi Purcaru

Reputation: 31524

  1. Instead a M2M table, you should use a ManyToManyField; this is quite the equivalent of what you did there with your Question_tags, but much more convenient.
  2. I don't know exactly what query do you want (please post some code...), but here are some examples which may clarify what you need to know:

    Question.objects.get(pk=some_question_id).question_tags_set.all()
    # get all tags of a specific `Question`
    Tags.objects.get(tagname="some_tag").question_tags_set.all()
    # all questions of a specific `Tag`
    

EDIT:

To change your models for ManyToManyField, use this:

class Tags(db.Model):
    tid = db.AutoField(primary_key=True)
    tagname = db.CharField(max_length=30)
    tag_cnt = db.IntegerField()

class Question(db.Model):
    userid = db.CharField(max_length=50)
    posted = db.DateTimeField(auto_now=True)
    question = db.TextField(max_length=500)
    qid = db.AutoField(primary_key=True)
    title = db.TextField(max_length=80)
    tags = db.ManyToManyField(Tags)

And you can get the values like this:

Question.objects.get(pk=123).tags.all()
Tags.objects.get(tagname="mytag").question_set.all()

# to count tags for every Question
from django.db.models import Count
Question.objects.all().annotate(num_tags=Count("tags"))

Upvotes: 2

Bernhard Vallant
Bernhard Vallant

Reputation: 50776

I assume you want to access the Question_tags and Tags objects from an Question object, which would mean you follow the foreign key relationship backwards.

question = Question.objects.get(pk=1)
question_tags = question.question_tags_set.all()

If you don't want to access the objects through FOO_setyou can set a related_name on the field in the model:

class Question_tags(db.Model):
    tag = db.ForeignKey('Tags', related_name="my_tag_objects")
    ques = db.ForeignKey('Question')

Nevertheless if your models are like that I think your Question_tags model is redundant and can be replaced by a ManyToManyField in Question.

Upvotes: 0

Related Questions