Django 使用ORM组合数据库请求数

Django 使用ORM组合数据库请求数,django,django-models,django-orm,Django,Django Models,Django Orm,我正在开发一个应用程序,用户可以对不同类别的不同项目进行投票和评论。每当用户返回站点时,他们的投票将突出显示,所有评论都将可见。 问题是,每次加载页面时,都会有许多数据库调用,这是由于我的模型设计或我没有找到有效的方法检索数据所致 我的模型如下: class ProjectCategory: title=models.CharField(...) class Project: category=models.ForeignKey(ProjectCategory) tit

我正在开发一个应用程序,用户可以对不同类别的不同项目进行投票和评论。每当用户返回站点时,他们的投票将突出显示,所有评论都将可见。 问题是,每次加载页面时,都会有许多数据库调用,这是由于我的模型设计或我没有找到有效的方法检索数据所致

我的模型如下:

class ProjectCategory:
    title=models.CharField(...)

class Project:
    category=models.ForeignKey(ProjectCategory)
    title=models.CharField(...)

    def ownedComments(self):
            return Comment.objects.filter(project=self).order_by('-submissionTime')

    def ownedCommentsPreview(self):
            return Comment.objects.filter(project=self).order_by('-submissionTime')[0:3]

    def ownedVotes(self):
            return Vote.objects.filter(project=self,upVoted=True).count() 


class Vote:
    project=models.ForeignKey(Project)
    user=models.ForeignKey(User)
    vote=models.IntegerField(...)

class Comment:
    project=models.ForeignKey(Project)
    user=models.ForeignKey(User)
    title=models.CharField(...)    
以下是我的视图的相关部分。py

def getCurrentUserData(request=None):
        if (request==None) or (request.user.is_authenticated()==False):
                return {'loggedInUsername':'Anonym','userIsLoggedIn':False}
        return {'loggedInUsername':request.user.username,'userIsLoggedIn':True}


def getProjectResponse(request,surveyFile=None,additionalInfo={}):
        userVotedUp=[]
        if surveyFile!=None:
                userVotes=Vote.objects.filter(upVoted=True,surveyFile=surveyFile)
                for vote in userVotes:
                        userVotedUp.append(vote.project.id)
        answerDict={'userVotedUp':userVotedUp,'prjCategories':PrjCategory.objects.select_related(),'projects': Project.objects.prefetch_related('category').filter(visible=True),'spammerquestion':spammerquestion.SpammerQuestion().getRandomQuestion(),'rotatingLines':helpers.getRandomRotatingLines(),'backgroundimageurl':helpers.getBackgroundImageUrl()}
        answerDict.update(getCurrentUserData(request))
        answerDict.update(additionalInfo)
        return answerDict

def showProject(request,prjNo):
        currentPrj=get_object_or_404(Project,prjNo=prjNo,visible=True)
        surveyFile=assignSurveyFile(request,create_surveyFile_if_not_existing=False)        
        return render_to_response('website/singleproject.html', getProjectResponse(request,surveyFile,{'currentPrj':currentPrj,'immediateProjectID':currentPrj.id}),context_instance=RequestContext(request))
模板包含项目和类别的许多迭代,这里可能会发生几个数据库调用。模板的相关部分包括:

{% for project in projects %}
    self.vote['{{ project.id }}']=ko.observable(new Vote({'totalVoteNumber':ko.observable({{ project.ownedVotes }}),'userVoteState':ko.observable({% if project.id in userVotedUp %}true{% else %}false{% endif %})}));
    self.comments['{{ project.id }}']=ko.observableArray([]);
    {% for comment in project.ownedCommentsPreview %}
        self.comments['{{ project.id }}'].push(new Comment({'description':'{{ comment.description|striptags|safe }}','submissionTime':'{{ comment.submissionTime|humanDT }}','commentUuid':'{{ comment.commentUuid }}','deletable':false}));
    {% endfor %}
{% endfor %}


        {% for prjCat in prjCategories %}
                .prjCatUnderline{{ prjCat.id }} {border-bottom: 0px solid {{ prjCat.color }};}
                .prjCatUnderline{{ prjCat.id }}:hover {border-bottom: 3px solid {{ prjCat.color }};}
        {% endfor %}


        {% for prjCat in prjCategories %}
                <a href="#" class="prjCatUnderline{{ prjCat.id }}" data-filter=".prjCat{{ prjCat.id }}">{{ prjCat.title }}</a>
                {% if not forloop.last %}<span class="catpipe">|</span>{% endif %}
        {% endfor %}

        <script type="text/javascript">
                var projectLocations = [{% for project in projects %}{% if project.location != '' %}['{{ project.title }}', {{ project.location }}, {{ project.id }}, '{{ MEDIA_URL }}{{ project.mapImage }}', {{ project.mapImage.width }}, {{ project.mapImage.height }}, '{{ project.id }}'],
                {% endif %}{% endfor %}];
        </script>


        {% for project in projects %}
                <div class="item prjCat{{ project.category.id }}">
                        <div class="prjnumberbox">
                                <div class="numberbar" style="background-color:{{ project.category.color }}"></div>
                                <div class="prjnumber">{{ project.prjNo|stringformat:"02d" }}</div>
                                <div class="numberbar" style="background-color: {{ project.category.color }}"></div>
                        </div>
                        <div class="prjheadline"><span>{{ project.title }}</span></div>
                        <div class="prjimagecontainer">
                                <!-- ko with: $root.vote['{{ project.id }}'] -->
                                <div class="prjimageoverlay"><a data-bind="click: function(data,event) { $root.showSingleProjectData('{{ project.id }}',data) },css : { imgVoted :userVoteState }" class="singleProjectOverlay" href="{% url 'website.views.showProject' prjNo=project.prjNo %}"></a></div>
                                <div class="prjimage"><img src="{{ MEDIA_URL }}{{ project.teaserImage }}" /></div>
                                <!-- /ko -->
                        </div>
                        <div class="prjtextcontainer" {% if project.ownedComments|length_is:"0" %}style="background-image:none;"{% endif %}>
                                <div class="prjtext">{{ project.teaserText|safe }} <a class="singleProjectOverlay" data-bind="click: function(data,event) { showSingleProjectData('{{ project.id }}',data) }" href="{% url 'website.views.showProject' prjNo=project.prjNo %}">mehr &gt;&gt;</a></div>
                                <div class="votesline"><span class="voteslinefont" data-bind="with: vote['{{ project.id }}']">&nbsp;<span class="votecount" data-bind="text: totalVoteNumber">{{ project.ownedVotes }}</span> votes&nbsp;</span></div>

                                <div class="prjcomments nojs">
                                {% for comment in project.ownedCommentsPreview|slice:":4" %}
                                        <div class="prjcommentitem">
                                                {{ comment.teaserdescription }}
                                        </div>
                                {% endfor %}
                                </div>
                                <div class="prjcomments" data-bind="foreach: comments['{{ project.id }}'], visible: comments['{{ project.id }}']().length > 0">
                                        <!-- ko if: $index() < 4 -->
                                        <div class="prjcommentitem">
                                                <em data-bind="text: submissionTime">&nbsp;</em><br/>
                                                <span data-bind="text: description">&nbsp;</span>
                                                <a href="#" data-bind="click: function(data, event) { $parent.removeComment(data,'{{ project.id }}', data,event) }, visible: deletable">[X]</a>
                                        </div>
                                        <!-- /ko -->

                                </div>
                        </div>
                </div>
        {% endfor %}
{%用于项目中的项目%}
self.vote['{project.id}}]=ko.observable(新投票({'totalVoteNumber':ko.observable({{project.ownedvoces}}),'userVoteState':ko.observable({%if project.id in userVotedUp%}真{%else%}假{%endif%}));
self.comments['{project.id}}']=ko.observearray([]);
{%project.ownedCommentsReview%中的注释%
self.comments['{project.id}}}].push(新注释({'description':{{{Comment.description{striptags{safe}}},'submissionTime':{{Comment.submissionTime{humanDT},'commentUuid':{{Comment.commentUuid},'deletable':false});
{%endfor%}
{%endfor%}
{prjCat在prjCategories%}
.prjCatUnderline{{prjCat.id}{边框底部:0px实心{{prjCat.color};}
.prjCat underline{{prjCat.id}:悬停{边框底部:3px实心{{prjCat.color};}
{%endfor%}
{prjCat在prjCategories%}
{%if不是forloop.last%}{%endif%}
{%endfor%}
var projectLocations=[{%for projects%}{%if project.location!=''%}[{{project.title}}},{{project.location},{{project.id},{{MEDIA_URL}{{project.mapImage},{project.mapImage.width},{{project.mapImage.height},{{project.id},
{%endif%}{%endfor%}];
{项目%中的项目为%}
{{project.prjNo | stringformat:“02d”}
{{project.title}
{{project.teaserText | safe}}
{{project.ownedVoces}}投票
{%project.ownedCommentsReview |切片:“:4”%}
{{comment.triserdescription}
{%endfor%}

{%endfor%}
对于首页,我想检索所有的项目,最近的三条评论,一个项目的投票总数,以及用户的评论和投票。 如果能通过一个db调用或两个db调用实现这一点,那就太好了,一个普通的db调用可以获得投票数和评论,另一个db调用可以获得特定于用户的数据

目前我正在通过一个调用检索所有项目,因此我将自动获取所有项目类别。然后我一次获得所有注释,并将它们分配给python中的项目。然后,我通过每次一次通话获得某个用户的评论和投票

有没有一种不直接使用sql的方法

  • 使用单个数据库调用的用户的注释和投票
  • 评论、项目、每个项目的累积投票数和项目类别

一个想法是使用select_related()下载整个数据库,然后用Python对所有内容进行排序,但如果将来我有大量的投票或评论,这可能不是一个好主意。

请显示您的视图代码和orm查询。@Jingo,谢谢您的评论。我添加了更多信息。