Come posso ottenere gli oggetti relativi a un extra di valori (). () Chiamata a Django?

StackOverflow https://stackoverflow.com/questions/1138360

  •  16-09-2019
  •  | 
  •  

Domanda

Grazie a questo post Sono in grado di fare facilmente contare e di gruppo per le query in una vista Django:

Django equivalente per il conteggio e il gruppo da

Quello che sto facendo nella mia app è la visualizzazione di un elenco di tipi di monete e valori nominali disponibili nel mio database per un paese, in modo da monete del Regno Unito potrebbe avere un valore nominale di "1 centesimo" o "6 pence". Il face_value è il 6, il currency_type è il "pence", memorizzata in una tabella correlata.

Ho il seguente codice a mio avviso che mi ottiene il 90% del tragitto:

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 } )

Il currency_type_id si presenta come il numero memorizzato nel campo chiave esterna (cioè 4). Quello che voglio fare è recuperare l'oggetto reale a cui fa riferimento come parte della query (il modello di valuta, in modo da poter ottenere il campo Currency.name nel mio modello).

Qual è il modo migliore per farlo?

È stato utile?

Soluzione 2

select_related() mi ha abbastanza vicino, ma voleva che io aggiungo ogni campo che ho scelto per la clausola group_by.

Così ho provato aggiungendo values() dopo la select_related(). No Go. Poi ho provato varie permutazioni di ciascuno in diverse posizioni della query. Vicino, ma non del tutto.

Ho finito "wimping out" e solo usando SQL prime, dal momento che già sapevo come scrivere query SQL.

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 } )

Se c'è un modo per frase quella query esatto nella lingua queryset Django sarei curioso di sapere. Immagino che un join SQL con un conteggio e raggruppamento da due colonne non è super-rara, quindi sarei sorpreso se non ci fosse un modo pulito.

Altri suggerimenti

Non si può farlo con values(). Ma non c'è bisogno di utilizzare tale -. Si può solo ottenere gli oggetti Collectible effettivi, e ognuno avrà un attributo currency_type che sarà l'oggetto collegato relativo

E come justinhamade suggerisce, utilizzando select_related() contribuirà a ridurre il numero di query di database.

Mettere insieme, si ottiene:

coin_values = Collectible.objects.filter(country=country.id, 
                    type=1).extra(
                    select={'count': 'count(1)'}, 
                    order_by=['-count']
                ).select_related()

Hai provato select_related () http: // docs. djangoproject.com/en/dev/ref/models/querysets/#id4

Io lo uso molto sembra funzionare bene allora si può andare coin_values.currency.name.

Anche io non penso che devi fare country = country.id nel filtro, basta country = paese, ma non sono sicuro che differenza che rende diverso da meno di battitura.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top