2009-09-19 4 views
0

Я хочу выполнить полукомплексный запрос в Django. Например, я хочу что-то вроде этого:Начало Django: выполнение подвыборок и другие сложные запросы

SELECT 
b.*, 
(SELECT count(id) FROM comments c WHERE c.blog_id = b.id) AS number_of_comments 
FROM blog b 
WHERE 1 

из моего PHP фона, код воспламенитель и Zend Framework имеет «запрос строителей». Где вы можете построить SQL-запрос, используя методы в рамках. Это что-то похожее на Django?

Что было бы лучшим способом создания и выполнения сложных запросов в Django? Есть ли рекомендуемый способ/наилучшая практика для выполнения подобных запросов?

UPDATE:

Я получил это работает с небольшими изменениями благодаря коду mherren ниже действующей. Вот обновленная версия кода.

В моем views.py я это:

def index(request): 
    blog_posts = Blog.objects.all().annotate(Count('comment')).order_by('-pub_date')[:5] 

    return render_to_response('blog/index.html', 
    {'blog_posts': blog_posts}) 

В моем файле шаблон (index.html) У меня есть это:

Welcome... 
{% if blog_posts %} 
    <ul> 
    {% for post in blog_posts %} 
     <li> 
      <b> 
      <a href="/blog/post/{{ post.id }}">{{ post.title }}</a> 
      </b> ({{ post.pub_date }})<br/> 
      {{ post.content }}<br/> 
      {{ post.comment__count }} comment(s)<br/> 
      by: {{ post.author }}<br/><br/> 
     </li> 
    {% endfor %} 
    </ul> 
{% else %} 
    <p>No posts are available.</p> 
{% endif %} 

Надеется, что это помогает также из других. Спасибо всем за ребята!

ответ

6

Вы можете сделать это, используя описанную агрегацию here.

Что-то любит:

class Post(models.Model): 
    title = models.CharField(max_length=200) 
    body = models.TextField() 
    #additional fields here... 

class Comment(models.Model): 
    post = models.ForeignKeyField(Post) 
    #additional fields here... 

... 

from django.db.models import Count 
from project.application.models import Post, Comment 

post_list = Post.objects.annotate(Count('comment_set')) 
for p in post_list: 
    print p.comment_set__count 
+0

Хммм. Я не уверен, что получаю это. Я посмотрю на ссылку, которую вы мне дали. Будет ли значение COUNT() включено в список полей, возвращаемый запросом? В моем примере выше я мог просто распечатать number_of_comments в моем «цикле» при итерации по каждой строке. – wenbert

+1

Да. Приведенный здесь код показывает итерацию через сообщения и печать comment_set__count для каждого. +1 Это правильный способ сделать это. –

+0

Это сработало для меня. Я сделал это так: blog_posts = Blog.objects.all(). Annotate (Count ('comment')). Order_by ('- pub_date') [: 5], а затем в моем шаблоне я напечатал: post.comment__count – wenbert

0

Не пытайтесь производить запросы SQL буквально в Django. Вы хотите рассчитать все комментарии к записи в блоге. Как простой цикл, это просто.

for b in Blog.objects.all(): 
    c = b.comment_set.count() 

Это код, который вы используете в Django вместо сложного SQL-запроса.

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

Пожалуйста, полностью прочитайте http://docs.djangoproject.com/en/dev/topics/db/queries/#topics-db-queries, чтобы получить доступ к данным в Django.

+0

Это это то, что я хочу. Итак, b.comment_set.count() будет содержать blog_id и результат count()? Или, если бы вы могли просто сказать мне, как сделать с переменными var_dump() в файле шаблона? Чтобы я мог просто узнать для себя. Благодаря! – wenbert

+0

@wenbert: Что? Это не SQL. 'b.comment_set.count()' - количество связанных объектов комментариев. 'b' - это сам объект Blog. 'b.id' - это внутренний идентификатор блога. 'b.somethingElse' - это еще один атрибут объекта Blog. –

+2

-1 Нет причин делать это таким образом (может привести к множеству SQL-запросов), когда ORM Django (начиная с 1.1) дает правильный способ сделать это в одном запросе (см. Ответ mherren). –

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