Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

Acceder a un attribut d'un modele django

+2 votes

J'ai un model django possedant un attribut tel que:

...
pub_date = models.DateField(name='date published', default=datetime.now)
...

Existe il une meilleure maniere d'acceder a cet attribut? Pour l'instant, j'ai ceci:

>>> i.pub_date
Traceback (most recent call last):
  File "<console>", line 1, in <module>
AttributeError: 'Photo' object has no attribute 'pub_date'
>>> getattr(i, 'date published')
datetime.date(2015, 2, 22)
>>> i.__dict__['date published']
datetime.date(2015, 2, 22)
>>> 
demandé 28-Mai-2015 par Nsukami_ (1,998 points)
remontrée 28-Mai-2015 par Nsukami_

en utilisant un accesseur? ;p

@boblinux pourquoi n'y ai je pas pensé? :\

Bon si c'est résolu fais signe que j'mette ça en réponse finale et qu'on close le sujet =D (si tu penses que c'est ce dont tu as besoin, à savoir utiliser un accesseur pour récupérer l'attribut)

@boblinux Mouais, accesseur en effet, parce que je vais retourner cet attribut, mais sous different format. Postez donc votre reponse, je vous en prie.

Hey, Nsukami_, ajouter un assesseur par dessus est peut etre le plus simple en apparance, mais c'est une tres mauvaise idée (pour rester poli)

Ici, l'essence de ton probleme c'est que tu a modifié le nom de ton field, nom qui sera utilisé pour y acceder en python (partie modele), pour de l'affichage dans une page web (partie vue). (j'assume encore que c'est pour l'admin django)

Derriere, cet attribut va etre mappé avec un champ en base de données. Ok, mettre des espaces dans un champ de base de données c'est valide syntaxyquement, mais c'est pas une raison pour le faire.
Tu te retrouverais avec un champ qui a 3 noms : le nom avec lequel tu l'as déclaré, le nom passé au prametre name, le nom de l'accesseur. Dans le genre confusant, on commence a etre pas mal.

Plusieurs questions :

  • est-ce que d'habitude tu mets des espaces dans le nom de tes attributs en python ? (la réponse est non évidement, c'est invalide)
  • est-ce que tu mets des espaces dans le nom de tes colonnes en BDD (ici j'espere que la reponse est non, a moins que tu sois masochiste en SQL. je ne juge pas ;) )
  • POURQUOI un forcer un nom qui est invalide en python, qui va te faire chier a la moindre requete SQL, rajouter du code par dessus (accesseur ou property) alors que tu peu régler le probleme a la base en faisant tout dans les regles de l'art ?

Ici, ton vrai probleme n'est pas de savoir comment accéder a un attribut mal nommé, mais comment bien utiliser l'ORM Django.

En d'autre termes : te tire pas une ballle dans le pied, cache pas les problemes sous le tapis, regle les au plus tôt ;)

@jc oh mon dieu, c'est effrayant :) balle ds le pied, probleme sous le tapis O_O. Vos deux reponses restent valides. Je vais me debarrasser de l'attribut avec un espace. Mais j'ai pas juste besoin de recuperer l'attribut, je dois egalement le formatter en fonction de certaines contraintes, quelque chose ds cet esprit:

    @property
    def pub_date_fr(self):
        return self.pub_date.strftime("%d-%m-%Y")

Top, rien a redire la dessus ;)

3 Réponses

+3 votes
 
Meilleure réponse

Suite a la reponse de @jc, je vais modifier mon modele pour avoir ceci:

pub_date = models.DateField(verbose_name='date published', default=datetime.now)

Suite a la suggestion de @boblinux et aussi, comme je souhaite pouvoir recuperer cet attribut en le formattant, je vais me servir de cette fonction:

@property
def pub_date_fr(self):
    return self.pub_date.strftime("%d-%m-%Y")
répondu 28-Mai-2015 par Nsukami_ (1,998 points)

Je rajoute, en complément de réponse, que tu peux aussi aussi formater ta date au niveau du template (voir le template filter date qui t’intéressera dans ce cas).

L'avantage c'est de respecter la logique MVC en décorrélant la data (le champs de ton modèle) avec la manière dont il s'affiche.

@jc Que serai je sans toi? Rien, je confirme!

sois pas si dur avec toi-même :)

+2 votes

En l'état, non a cause de l'espace dans le nom de l'attribut (que tu redéfini avec le paramètre 'name') : ce n'est pas un identifier python valide.

Je suppose que l'espace est la pour avoir un affichage 'humain' dans l'admin -> si c'est le cas, utilise plutôt le paramètre 'verbose_name' au lieu de 'name'.

pub_date = models.DateField(verbose_name='date published', default=datetime.now)

https://docs.djangoproject.com/en/1.8/ref/models/fields/#verbose-name.

répondu 28-Mai-2015 par jc (2,704 points)
–2 votes

Existe il une meilleure manière d'accéder a cet attribut?

La meilleur façon d'accéder à un attribut c'est d'utiliser un accesseur.
En effet, ça permet de préserver la sécurité de la classe en nous empêchant de modifier les attributs de celle-ci, on peut juste y avoir accès pour la consulter.

petit exemple :

import myclass from mymodule

>> myclass.AttributA # ça foire car on a n'a pas accès à l'attribut qui est privé

Traceback (most recent call last):
  File "<console>", line 1, in <module>
AttributeError: 'myclass' object has no attribute 'AttributA'

>> a = myclass.GetAttributA # Maintenant on peut consulter l'attribut privé via l'accesseur
répondu 28-Mai-2015 par boblinux (3,092 points)

Downvote, cf mon commentaire

Et j'aurais bien downvote une seconde fois pour cette phrase :

La meilleur façon d'accéder à un attribut c'est d'utiliser un accesseur.

La meilleur facon d'accéder a un attribut, c'est d'accéder a un attribut. Comme on dit : "We're all responsible users here"

...