Comment puis-je obtenir les objets liés dans un appel supplémentaire (). Les valeurs () dans Django?

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

  •  16-09-2019
  •  | 
  •  

Question

Merci à ce poste, je suis capable de faire facilement compter et le groupe par des requêtes en vue Django:

Django équivalent pour le comptage et le groupe de

Ce que je fais dans mon application affiche une liste des types de pièces de monnaie et des valeurs faciales disponibles dans ma base de données pour un pays, de sorte que des pièces de monnaie du Royaume-Uni pourraient avoir une valeur nominale de « 1 liard » ou « 6 pence ». Le face_value est le 6, le currency_type est le "pence", stocké dans une table associée.

Je le code suivant à mon avis qui me fait 90% du chemin:

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

Le currency_type_id apparaît comme le numéro stocké dans le champ de clé étrangère (par exemple 4). Ce que je veux faire est de récupérer l'objet réel qu'il fait référence dans le cadre de la requête (le modèle de monnaie, afin que je puisse obtenir le champ Currency.name dans mon modèle).

Quelle est la meilleure façon de le faire?

Était-ce utile?

La solution 2

select_related() m'a assez proche, mais il voulait que je ajouter tous les domaines que je l'ai choisi à la clause group_by.

J'ai donc essayé annexant values() après la select_related(). Ne pas aller. Alors j'ai essayé différentes permutations de chacun dans différentes positions de la requête. Fermer, mais pas tout à fait.

J'ai fini « wimping out » et juste en utilisant SQL brut, depuis que je savais déjà comment écrire la requête 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 } )

S'il y a une façon de formuler cette requête exacte dans la langue queryset Django je serais curieux de savoir. Je suppose que les jointures SQL avec un nombre et le regroupement par deux colonnes est pas super rare, donc je serais surpris s'il n'y avait pas une manière propre.

Autres conseils

Vous ne pouvez pas le faire avec values(). Mais il n'y a pas besoin d'utiliser ce -. Vous pouvez simplement obtenir les objets réels Collectible, et chacun aura un attribut currency_type qui sera l'objet lié concerné

Et comme justinhamade suggère, en utilisant select_related() aidera à réduire le nombre de requêtes de base de données.

Mettre ensemble, vous obtenez:

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

Avez-vous essayé select_related () http: // docs. djangoproject.com/en/dev/ref/models/querysets/#id4

Je l'utilise beaucoup, il semble bien fonctionner alors vous pouvez aller coin_values.currency.name.

Aussi je ne pense pas que vous devez faire country = country.id dans votre filtre, tout pays = pays, mais je ne suis pas sûr de ce qui fait la différence autre que moins de frappe.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top