2013-10-07 3 views
-1

У меня есть приложение, подобное reddit. Есть «сообщения», и люди голосуют по ним вверх или вниз. В моем шаблоне я перечисляю все сообщения, и я хочу указать, проголосовал ли человек за сообщение или нет.Django querysets и внешние ключи

Это немного запутанно, потому что я передаю свой запрос, полный сообщений, в шаблон, но по мере того, как я перебираю каждое сообщение для его отображения, я также хочу знать, существует ли существующее голосование или нет.

Вот код:

class Submission(models.Model): 
    submitter = models.ForeignKey(User) 
    title = models.CharField("Title", max_length=200) 

class Vote(models.Model): 
    voter = models.ForeignKey(User) 
    submission = models.ForeignKey(Submission) 
    vote_value = models.FloatField() 

class SubmissionListView(ListView): 
    model = Submission 
    queryset = Submission.objects.extra(select={'total': 'IFNULL((SELECT SUM(vote_value) ' + \ 
     'FROM submissions_vote ' + 'WHERE submissions_vote.submission_id = ' + 'submissions_submission.id), ' + \ 
     '0)'}).order_by('-total') 
    paginate_by = 5 

Ok, так что вы можете видеть, что я делаю QuerySet дополнительного(), потому что я хочу, чтобы суммировать все голоса для каждой должности и отображение всего на этой странице. Я думаю, что это самый эффективный способ сделать это.

Но если пользователь, просматривающий страницу, сделал голосование за конкретное представление, мне нужно каким-то образом передать эту информацию в шаблон. Я знаю, что могу прокрутить каждый объект голосования в шаблоне и понять его там, но это кажется действительно неэффективным. Я читал о цепочке запросов ... это то, что мне нужно сделать здесь?

ответ

2

Вы можете добавить еще extra выберите:

queryset = Submission.objects.extra(
    select={'total': 'IFNULL((SELECT SUM(vote_value) ' + \ 
     'FROM submissions_vote ' + 'WHERE submissions_vote.submission_id = ' + \ 
     'submissions_submission.id), ' + '0)', 
    'has_voted': 'CASE WHEN %d IN (SELECT voter_id FROM submissions_vote WHERE ' + \ 
     'submissions_vote.submission_id = submissions_submission.id) THEN 1 ELSE 0 END' 
    }, select_params=(self.request.user.pk,)).order_by('-total') 

Я знаю, что это не самый красивый решение. Обычно я стараюсь не писать собственные SQL-файлы слишком часто, но я не могу придумать ничего лучшего. Хотелось бы узнать, что вы делаете.

EDIT: так как вы должны иметь доступ к self.request, необходимо переопределить метод get_queryset:

def get_queryset(self): 
    return Submission.objects.extra(
    select={'total': 'IFNULL((SELECT SUM(vote_value) ' + \ 
     'FROM submissions_vote ' + 'WHERE submissions_vote.submission_id = ' + \ 
     'submissions_submission.id), ' + '0)', 
    'has_voted': 'CASE WHEN %d IN (SELECT voter_id FROM submissions_vote WHERE ' + \ 
     'submissions_vote.submission_id = submissions_submission.id) THEN 1 ELSE 0 END' 
    }, select_params=(self.request.user.pk,)).order_by('-total') 

ли, что вместо queryset переменной

+0

Ммм .. Мне нравится ваша идея, но я могу Кажется, что к этому моменту я получил доступ к self.request.user.pk. Наверное, потому что на данный момент я недоступен? – asolberg

+0

А мне плохо. Я не понимал, где вы определяете запрос. Я отредактировал свой ответ, чтобы исправить это. – jproffitt

+0

Да, это похоже на работу. За исключением того, что мне действительно нужно поле «vote_value», которое нужно вернуть, чтобы я мог сказать, идет ли голосование вверх или вниз. Я попытался сказать, тогда выберите voter_id, vote_value ..... then vote_value else 0, но это не сработало. – asolberg

Смежные вопросы