2016-04-27 5 views
0


Ich brauche etwas Hilfe. Mein Problem ist, dass ich versuche, mehrere Tabellen/Modelle ((Frage, Antwort, Benutzer)) in Django 1.9 zu verbinden, um zu erhalten, wie viele Antworten eine Fragegruppe von einem bestimmten Benutzer haben.Wie kann ich mehrere Tabellen in Django 1.9 verbinden?

Ich habe bereits eine SQL-Abfrage von dem, was ich will:

SELECT q.id, q.title, COUNT(a.id) AS total_answers 
FROM review_question AS q 
JOIN review_answer AS a ON q.id = a.question_id 
JOIN users_user AS u ON q.user_id = u.id 
WHERE q.user_id = 1 
GROUP BY q.id, q.title; 

Und hier sind meine Modelle:

Bewertung/models.py

[Frage]

class Question(models.Model): 
    user = models.ForeignKey(User, db_index=True, null=True, blank=True) 
    tag = models.ManyToManyField(Tag) 
    title = models.CharField(max_length=200) 

[Antwort]

class Answer(models.Model): 
    question = models.ForeignKey(Question) 
    user = models.ForeignKey(User, db_index=True, null=True, blank=True) 

Benutzer/models.py

[Benutzer]

class User(models.Model): 
    username = models.CharField(max_length=100, unique=True) 

By the way, in meiner Datei Benutzer/views.py Ich habe die nächste:

class UserDetailView(DetailView): 
    model = User 

    def get_context_data(self, **kwargs): 
     # calling the get_context_data parent here 
     questions = Question.objects.filter(user = context['object']).order_by('created') 

aber ich bekomme nur alle Fragen, die der Benutzer gemacht hat.

Ich habe seit einiger Zeit versucht, einen Weg zu finden, wie man die Abfrage von oben in den Django-Orm übersetzt, aber das kann ich immer noch nicht erreichen. Jede Hilfe wäre zu schätzen.

+0

Sie sind auf dem halben Weg. Nun, da Sie die Fragen "Answer.objects.filter (question__in = questions)" haben. Überprüfen Sie dies: https://docs.djangoproject.com/es/1.9/ref/models/querysets/#in – MikeVelazco

+0

Wie wäre es mit 'Answer.objects.filter (question__user = user)'? EDIT: Ich hatte die GROUP BY in Ihrer Abfrage nicht bemerkt, mein Vorschlag wird das nicht tun. –

+0

@MikeVelazco Danke, ich werde es überprüfen und sehen, was kann ich tun;) –

Antwort

0

Endlich konnte ich meinem Problem helfen.

Was ich tat, war der nächste:

in meiner Datei Benutzer/views.py

class UserDetailView(DetailView): 
    model = User 

    def get_context_data(self, **kwargs): 
     # Calling the get_context_data parent 
     questions = Question.objects.filter(user = context['object']).order_by('created') 

     tags = [ question.tag.all() for question in questions ] 

     total_answers = self.get_total(questions) # Calling the function that return the total answer by question of a specific user 
     context['question_tags'] = zip(questions, tags, total_answers) #Zipping the lists with results to use it in the template 

     return context 

    def get_total(self, questions): 
     #Return the total answers that a question has (Here is the trick!) 
     return [ 
      Answer.objects.filter(question__id=question.id).annotate(num_answers=Count('question')).count() for question in questions] 

Tha alles wurde ich. Zum Schluss möchte ich mich ganz besonders bei @PauloAlmeida und @MikeVelazco für die Hilfe bedanken!

+1

Wenn Sie ein Listenverständnis verwenden, können Sie wahrscheinlich einfach [question.answer_set.count() für Fragen in Fragen] zurückgeben. –

+0

Ja, du hast Recht. Sieht jetzt besser aus;) Aber könnten Sie mir das erklären? .answer_set.count() 'Ich verstehe es nicht sehr gut. –

+0

Es ist in Ordnung, ich habe es bereits in der Dokumentation gefunden. Sieht so aus, als wäre es ein besserer Weg. Danke nochmal. –