2016-03-21 7 views
2

ich in einem Projekt bin, wo ich diesenDjango ORM, ein Parameter verschiedener

mt = Model.objects.get(pk=2) 
if mt.quantity > 0 and not ModelClass.objects.filter(a=mt.a, b = mt.b, c=mt.c, low__lte=mt.rate).exists(): 
    ----Do Something 
elif mt.quantity < 0 and not ModelClass.objects.filter(a=mt.a, b=mt.b, c=mt.c, high__gte=mt.rate).exists(): 
    ---Do Same as above 

täte Gibt es eine andere Art und Weise Pythonic dies zu tun.

Diese Frage ist nur für akademisches Interesse, da mein Ziel mit dem oben genannten erreicht wird.

Vielen Dank.

EDIT: Ich kann OR auch dafür verwenden, aber ich würde gerne wissen, ob dies in einer kompakten Weise erreicht werden kann.

EDIT 2: Die beiden Modelle, d. H. Model und ModelClass, sind durch keinen Fremdschlüssel miteinander verwandt.

+1

Sind 'Model' und' ModelClass' irgendwie verwandt? –

+0

sie sind nicht verwandt, d. H. Kein Fremdschlüssel. aber es gibt mehr Filter in diesem. Ich werde bearbeiten. – user1572215

Antwort

2

Die lesbarer Weise die gleichen Filter in jeder Klausel ohne Wiederholung ist wahrscheinlich diese:

mt = Model.objects.get(pk=2) 
qs = ModelClass.objects.filter(a=mt.a, b = mt.b, c=mt.c) 
if mt.quantity > 0 and not qs.filter(low__lte=mt.rate).exists(): 
    ----Do Something 
elif mt.quantity < 0 and not qs.filter(high__gte=mt.rate).exists(): 
    ---Do Same as above 

Wenn Sie einige Python-spezifische Konstrukte verwenden möchten können Sie auch bauen nur das Schlüsselwort Argumente für die filter():

kwargs = dict(a=mt.a, b=mt.b, c=mt.c) 
if mt.quantity > 0: 
    kwargs.update({'low__lte': mt.rate}) 
if mt.quantity < 0: 
    kwargs.update({'high__gte': mt.rate}) 
if ModelClass.objects.filter(**kwargs).exists(): 
    # do some stuff 
2

Sie könnten die gemeinsamen Teile des Filters in einen queryset ausklammern, um zu verhindern Duplizierung:

query = ModelClass.objects.filter(a=mt.a, b = mt.b, c=mt.c) 

if mt.quantity > 0 and not query.filter(low__lte=mt.rate).exists(): 
    ----Do Something 
elif mt.quantity < 0 and not query.filter(high__gte=mt.rate).exists(): 
    ---Do Same as above 

Am Vorteil der Verwendung eines or Aussage ist, dass Sie nicht den Code in ‚Tun Sie etwas‘ duplizieren . Sie können diesen Code in eine einzige Methode do_something() ausschließen, um eine Duplizierung zu verhindern.

Ein anderer Weg, um die Vervielfältigung zu verhindern, ist ein Flag zu verwenden:

do_something = False 
if mt.quantity > 0 and not query.filter(low__lte=mt.rate).exists(): 
    do_something = True 
elif mt.quantity < 0 and not query.filter(a=mt.a, b=mt.b, c=mt.c, high__gte=mt.rate).exists(): 
    do_something = True 

if do_something: 
    # do the thing 

Manchmal ist es sinnvoll, dynamische Argumente zu verwenden. In diesem Fall würde Ihr Code jedoch wahrscheinlich komplizierter als nötig werden.

query = {} 
if mt.quantity > 0: 
    query['low__lte'] = mt.rate 
elif mt.quantity < 0: 
    query['high__gte'] = mt.rate 
if mt.quantity != 0 and ModelClass.objects.filter(a=mt.a, b = mt.b, c=mt.c, **query).exists(): 
    # do something 

Manchmal können Sie Q() Objekte verwenden komplexe Filter

ModelClass.objects.filter(Q(low__lte=mt.rate)|Q(high__gte=mt.rate)).exists(): 

jedoch zu tun, dass Sie in diesem Fall nicht hilft, weil Sie auch mt.quantity in der if-Anweisungen überprüft werden.

+0

gibt es einen Tippfehler, Filter sind in elif in den ersten beiden dupliziert. – user1572215

+0

Danke, jetzt behoben. – Alasdair

Verwandte Themen