use*_*605 2 python django django-views
我通常不会以最好的方式编写我的Python代码,因为我对它比较新,有人要求我对Django应用程序进行更改,因为代码看起来不太好.
这是它的样子:
@login_required
def submission_set_rank(request):
r1_obj_id = request.GET.get('rank1','')
r2_obj_id = request.GET.get('rank2','')
r3_obj_id = request.GET.get('rank3','')
r4_obj_id = request.GET.get('rank4','')
r5_obj_id = request.GET.get('rank5','')
#rate the first BallotStats object
ballot_1 = BallotStats.objects.get(object_id=r1_obj_id)
ballot_2 = BallotStats.objects.get(object_id=r2_obj_id)
ballot_3 = BallotStats.objects.get(object_id=r3_obj_id)
ballot_4 = BallotStats.objects.get(object_id=r4_obj_id)
ballot_5 = BallotStats.objects.get(object_id=r5_obj_id)
ballot_1.score += 5
ballot_2.score += 4
ballot_3.score += 3
ballot_4.score += 2
ballot_5.score += 1
ballot_1.save()
ballot_2.save()
ballot_3.save()
ballot_4.save()
ballot_5.save()
return HttpResponseRedirect('/submissions/results/film/')
Run Code Online (Sandbox Code Playgroud)
事实证明,我意识到我一直在用这种方式编写我的Python代码,有没有办法让它看起来更好而不是占用21行代码?
在你的情况下,一点点的循环根本不会受到伤害.事实上,作为一般规则,每当你不得不重复两次以上的事情时,试着让它成为一个循环.
n = 5
for i in range(1, n+1):
obj_id = request.GET('rank' + str(i), '')
ballot = BallotStats.objects.get(object_id=obj_id)
ballot.score += n - i + 1
ballot.save()
Run Code Online (Sandbox Code Playgroud)
最大的问题不是代码的样式 - 而是你要进行10次查询:5个用于获取对象,5个用于更新它们.
立即过滤掉对象__in:
@login_required
def submission_set_rank(request):
keys = {'rank1': 5, 'rank2': 4, 'rank3': 3, 'rank4': 2, 'rank5': 1}
ranks = [request.GET.get(key,'') for key in keys]
for ballot in BallotStats.objects.filter(object_id__in=ranks):
ballot.score += keys[ballot.object_id]
ballot.save()
return HttpResponseRedirect('/submissions/results/film/')
Run Code Online (Sandbox Code Playgroud)
这将最多进行6个查询:1个用于获取对象,5个用于更新它们.
此外,您可以使用commit_manually装饰器"标记"视图(commit_on_success也适用于您).它应该显着加速事情:
@login_required
@transaction.commit_manually
def submission_set_rank(request):
keys = {'rank1': 5, 'rank2': 4, 'rank3': 3, 'rank4': 2, 'rank5': 1}
ranks = [request.GET.get(key,'') for key in keys]
for ballot in BallotStats.objects.filter(object_id__in=ranks):
ballot.score += keys[ballot.object_id]
ballot.save()
transaction.commit()
return HttpResponseRedirect('/submissions/results/film/')
Run Code Online (Sandbox Code Playgroud)
而且我有强烈的感觉,你甚至可以在一个更新查询中执行此操作.例如,通过以下方式 connection.cursor()直接使用executemany():
@login_required
def submission_set_rank(request):
keys = {'rank1': 5, 'rank2': 4, 'rank3': 3, 'rank4': 2, 'rank5': 1}
ranks = [{'score': request.GET.get(key,''), 'id': key} for key in keys]
cursor = connection.cursor()
cursor.executemany("""
UPDATE
ballot_stats
SET
score = score + %(score)s
WHERE
object_id = %(id)s
""", ranks)
return HttpResponseRedirect('/submissions/results/film/')
Run Code Online (Sandbox Code Playgroud)
确保字段和表名称正确.
| 归档时间: |
|
| 查看次数: |
125 次 |
| 最近记录: |