Wie erhalte ich die entsprechenden Objekte in einem extra (). Werte () -Aufruf in Django?
-
16-09-2019 - |
Frage
Dank zu diesem Beitrag ich in der Lage bin, die von Abfragen in einem Django-View zählt und Gruppe leicht tun:
Django Äquivalent für Zählung und Gruppe von
Was ich in meiner app mach ist eine Liste von Münzsorten und Nennwerten Anzeigen in meiner Datenbank für ein Land, so Münzen aus dem Vereinigten Königreich einen Nennwert von „1 Farthing“ haben könnten oder „6 Pence“. Die face_value
ist die 6, die currency_type
ist die "Pence", in einer verknüpften Tabelle gespeichert.
Ich habe den folgenden Code in meiner Ansicht, die mir 90% der Art und Weise wird es:
def coins_by_country(request, country_name):
country = Country.objects.get(name=country_name)
coin_values = Collectible.objects.filter(country=country.id, type=1).extra(select={'count': 'count(1)'},
order_by=['-count']).values('count', 'face_value', 'currency_type')
coin_values.query.group_by = ['currency_type_id', 'face_value']
return render_to_response('icollectit/coins_by_country.html', {'coin_values': coin_values, 'country': country } )
Die currency_type_id
wirken wie die Anzahl in dem Fremdschlüsselfeld gespeichert (d 4). Was ich tun möchte, ist das eigentliche Objekt abrufen, dass es als Teil der Abfrage verweist (das Währungsmodell, so kann ich das Currency.name Feld in meiner Vorlage bekommen).
Was ist der beste Weg, das zu tun?
Lösung 2
select_related()
hat mich ziemlich nah dran, aber es wollte, dass ich jedes Feld hinzufügen, dass ich auf die group_by
Klausel ausgewählt haben.
Also habe ich versucht values()
nach dem select_related()
anhängt. No Go. Dann habe ich versucht, verschiedene Permutationen von jeweils in unterschiedlichen Positionen der Abfrage. Close-up, aber nicht ganz.
Ich landete „wimping out“ und nur rohe SQL verwenden, da ich bereits wusste, wie die SQL-Abfrage zu schreiben.
def coins_by_country(request, country_name):
country = get_object_or_404(Country, name=country_name)
cursor = connection.cursor()
cursor.execute('SELECT count(*), face_value, collection_currency.name FROM collection_collectible, collection_currency WHERE collection_collectible.currency_type_id = collection_currency.id AND country_id=%s AND type=1 group by face_value, collection_currency.name', [country.id] )
coin_values = cursor.fetchall()
return render_to_response('icollectit/coins_by_country.html', {'coin_values': coin_values, 'country': country } )
Wenn es ein Weg Begriff ist, die genaue Abfrage in der Django queryset Sprache, die ich neugierig sein würde zu wissen. Ich stelle ich vor, dass eine SQL von zwei Säulen mit einer Zählung und Gruppierung beizutreten, ist nicht super-rare, also würde ich überrascht, wenn es nicht eine saubere Art und Weise ist.
Andere Tipps
Sie können es mit values()
nicht tun. Aber es gibt keine Notwendigkeit zu verwenden, dass -. Sie können nur die tatsächlichen Collectible
Objekte bekommen, und jeder wird ein currency_type
Attribut haben, dass das relevante verknüpfte Objekt sein
Und wie justinhamade schon sagt, select_related()
Verwendung wird dazu beitragen, die Anzahl der Datenbankabfragen zu reduzieren.
Um es zusammen, erhalten Sie:
coin_values = Collectible.objects.filter(country=country.id,
type=1).extra(
select={'count': 'count(1)'},
order_by=['-count']
).select_related()
Haben Sie versucht select_related () http: // docs. djangoproject.com/en/dev/ref/models/querysets/#id4
Ich benutze es viel es scheint gut zu funktionieren, dann können Sie coin_values.currency.name gehen.
Auch ich glaube nicht, Sie brauchen Land = country.id in Ihrem Filter zu tun, nur country = Land, aber ich bin nicht sicher, was für einen Unterschied, die als weniger tippen andere machen.