2012-07-23 1 views
2

Plusieurs fois dans les codes open source de python django, j'ai vu le scénario comme celui-ciQuelle est la meilleure façon de vérifier les conditions de demande?

if request.META and 'HTTP_REFERER' in request.META: 

De même je l'ai vu ces deux si les conditions aussi

if request.POST and 'next' in request.POST: 
if request.GET and 'next' in request.GET: 

Je crois que seule condition est suffire pour vérifier la condition if dans ces cas comme

if 'HTTP_REFERER' in request.META: 
if 'next' in request.POST: 
if 'next' in request.GET: 

Alors pourquoi la plupart du temps les gens utilisent le plus tôt une fois, Est-ce que c'est juste comme une double vérification ou des scénarios dans lesquels les premières conditions de double contrôle peuvent être utiles alors que les conditions de contrôle unique ultérieures peuvent échouer?

Répondre

2

Je viens de l'ensemble rassemblés de (git courant) source de django, et n'avait pas trouvé une seule occurrence des trois conditions que vous avez mentionnées.

Et vous avez parfaitement raison avec la seule condition suffisante comme long comme vous pouvez supposer que tous les trois dictionnaires sont définis. Et en regardant le code django, je crois que vous pouvez le supposer.

Modifier: également le django documentation suggère que ces dictionnaires seront toujours définis.

2

Il y a un (hypothétique) cas où votre solution échouerait:

>>> request.POST = None 
>>> 'next' in request.POST 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: argument of type 'NoneType' is not iterable 

Mais si vous pouvez être sûr que request.POST ne sera jamais None, votre solution serait OK.

Il est juste un peu plus lent dans le cas d'un dictionnaire vide car le test if 'foo' in request.POST peut être ignoré si le test (rapide) de vide échoue déjà. D'un autre côté, ce sera plus rapide si le dictionnaire n'est pas vide.

>>> import timeit 
>>> timeit.timeit(setup="a = {}", stmt="if a and 'next' in a: pass") 
0.028279806566242852 
>>> timeit.timeit(setup="a = {}", stmt="if 'next' in a: pass") 
0.04539217556517272 
>>> timeit.timeit(setup="a = {'foo':'bar'}", stmt="if a and 'next' in a: pass") 
0.07471092295071458 
>>> timeit.timeit(setup="a = {'foo':'bar'}", stmt="if 'next' in a: pass") 
0.045236056421884996 
>>> timeit.timeit(setup="a = {'next':'bar'}", stmt="if a and 'next' in a: pass") 
0.0851067469988891 
>>> timeit.timeit(setup="a = {'next':'bar'}", stmt="if 'next' in a: pass") 
0.0520663758715898 

Donc je suppose que c'est une question de micro-optimisation. Dans ce cas, j'invoque le Zen de Python: Explicit est meilleur qu'implicite.

+0

Je ne pense pas que request.POST peut être None, à moins que quelqu'un ne lui donne explicitement la valeur None. –

+0

Michał Górny soutient votre point de vue. @PiyusG dit le contraire. Je ne suis pas sûr de qui a raison :) –

+0

Qu'il parle des valeurs des paramètres comme Aucun, pas le request.POST lui-même. Ca peut être {} mais pas None je suppose ... après tout POST et GET sont seulement l'instance du dictionnaire Query lui-même Donc ils ne peuvent pas être None par eux-mêmes. –

8

Il peut être acheived que par la vérification
request.META.get('HTTP_REFERER') et
request.REQUEST.get('next')
au lieu de vérifier pour request.POST ou request.GET

+2

Je ne me souviens pas si django a de la magie pour ça, mais comment pourrait-il gérer '? Next = '(c'est-à-dire la valeur vide)? –

+1

Dans la requête GET, le type request.REQUEST.get ('next') vous renverra '' if? Next = est ce qu'il vous donnera? – PiyusG

+0

Et Python vous donnera 'false' pour une valeur vide alors que la vérification de clé donnera vous 'vrai'. –

Questions connexes