web-dev-qa-db-fra.com

Comment renommer des éléments dans values ​​() dans Django?

Je veux faire à peu près la même chose que dans ce ticket sur djangoproject.com , mais avec un formatage supplémentaire. De cette requête

>>> MyModel.objects.values('cryptic_value_name')
[{'cryptic_value_name': 1}, {'cryptic_value_name': 2}]

Je veux obtenir quelque chose comme ça:

>>> MyModel.objects.values(renamed_value='cryptic_value_name')
[{'renamed_value': 1}, {'renamed_value': 2}]

Existe-t-il un autre moyen plus intégré ou dois-je le faire manuellement?

81
Martin

C'est un peu hacky, mais vous pouvez utiliser la méthode extra :

MyModel.objects.extra(
  select={
    'renamed_value': 'cryptic_value_name'
  }
).values(
  'renamed_value'
)

Cela fait essentiellement SELECT cryptic_value_name AS renamed_value dans le SQL.

Une autre option, si vous voulez toujours la version renommée mais que la base de données a le nom cryptique, est de nommer votre champ avec le nouveau nom mais utilisez db_column pour faire référence au nom d'origine dans la base de données.

58
Daniel Roseman

À partir de Django>=1.8, Vous pouvez utiliser l'annotation et l'objet F

from Django.db.models import F

MyModel.objects.annotate(renamed_value=F('cryptic_value_name')).values('renamed_value')

extra() va également être dépréciée, à partir des Django docs:

Il s'agit d'une ancienne API que nous visons à déconseiller à un moment donné dans le futur. Utilisez-le uniquement si vous ne pouvez pas exprimer votre requête à l'aide d'autres méthodes de jeu de requêtes. Si vous en avez besoin, veuillez déposer un ticket à l'aide du mot clé QuerySet.extra avec votre cas d'utilisation (veuillez d'abord vérifier la liste des tickets existants) afin que nous puissions améliorer l'API QuerySet pour permettre la suppression de extra (). Nous n'améliorons ni ne corrigeons plus de bogues pour cette méthode.

146
alejandrodnm

Sans utiliser aucune autre méthode de gestion (testé sur v2.0.8):

from Django.db.models import F

MyModel.objects.values(renamed_value=F('cryptic_value_name'))
50
Arpit Singh

Je travaille avec Django 1.11.6

(Et la clé: la paire de valeurs est opposée à celle de la réponse acceptée)

Voici comment je le fais fonctionner pour mon projet

def json(university):
    address = UniversityAddress.objects.filter(university=university)
    address = address.extra(select={'city__state__country__name': 'country', 'city__state__name': 'state', 'city__name': 'city'})
    address = address.values('country', 'state', "city", 'street', "postal_code").get()
    return address

Notez que l'ajout simultané de objects.filter (). Extra (). Values ​​() est le même que ci-dessus.

0
Sudip Bhattarai