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 >></a></div>
<div class="votesline"><span class="voteslinefont" data-bind="with: vote['{{ project.id }}']"> <span class="votecount" data-bind="text: totalVoteNumber">{{ project.ownedVotes }}</span> votes </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"> </em><br/>
<span data-bind="text: description"> </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,谢谢您的评论。我添加了更多信息。