Définir un mixin dans le fichier settings.py

Le problème exposé dans ce sujet a été résolu.

Bonjour,

Je travaille avec Python 3.5 et Django 1.10 et je me retrouve avec le problème suivant. J’ai une classe Member qui représente un membre de mon association. En particulier, cette personne dispose d’une adresse. En France, elle serait du type (street, postcode, city).

Or, pour plus de flexibilité, je souhaiterais pouvoir rendre le type d’adresse configurable (par exemple, si quelqu’un souhaite ajouter un attribut numero). Je pensais donc permettre à l’utilisateur de l’app de définir un mixin dans le fichier settings.py, dont mon model Member hériterait :

user_app/models/postal_address.py :

1
2
3
4
5
class PostalAddressMixin(models.Model):
    # ...

    class Meta:
        abstract = True

settings.py :

1
2
import user_app
PostalAddressMixin = user_app.models.postal_address.PostalAddressMixin

app/models/member.py :

1
2
class Member(settings.PostalAddressMixin):
    # ...

Seulement, Django me dit django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet. lors de l’exécution de la commande ./manage.py makemigrations user_app.1 D’ailleurs, je n’ai pas vu de méthode similaire sur le web, donc j’imagine qu’elle est mauvais.

Une autre solution serait de procéder ainsi :

1
2
3
class Member(models.Model):
    # ...
    address = models.OneToOneField(settings.POSTAL_ADDRESS_MODEL)
1
POSTAL_ADDRESS_MODEL = 'user_app.models.PostalAddress'

Seulement, ça implique que mon modèle PostalAddress a une existence propre, que je peux en créer des instances non rattachées à un membre, ce qui n’a pas de sens. Et puis c’est beaucoup moins naturel dans le site d’administration de renseigner l’adresse via une clé étrangère.

Auriez-vous des conseils à ce sujet ?

Merci.


  1. Edit : il semblerait que ce soit dû au fait que user_app/__init__.py contenait from . import models

+0 -0

C’est pas une bonne idée de mettre du code dans les settings. De façon générale, si ça ne tient qu’à moi, tant que personne ne te demande cette fonctionnalité, tu ne devrais pas t’en occuper.

Ensuite si une personne veut modifier le modèle, elle peut très bien modifier ton code.

Enfin, avec le peu de détails que tu donne, perso je ferai plutôt un user qui possède un GenericForeignKey vers une classe UserProfile qui peut être hérité simplement. Comme ça ton user ne stocke pas les données directement mais peut être lié à un autre modèle sans savoir à priori ce qu’il contient.

Merci pour ta réponse.

De façon générale, si ça ne tient qu’à moi, tant que personne ne te demande cette fonctionnalité, tu ne devrais pas t’en occuper.

Oui, mais là il s’agit d’un projet personnel. Je n’ai pas de contraintes de temps, donc j’essaye de me former à produire du code propre.

Ensuite si une personne veut modifier le modèle, elle peut très bien modifier ton code.

Oui mais ce n’est pas pratique pour elle, si ? Je veux dire, ça introduit un conflit dans le dépôt git donc les mises à jour risquent d’être laborieuses.

je vais jeter un oeil aux GenericForeignKeys, merci.

+0 -0

C’est effectivement une GenericForeignKey qui serait la bonne solution à mon avis aussi.

L’utilisateur de ton app django pourra l’inclure dans son projet, et y configurer un modèle Member custom.

+0 -0

Oui mais ce n’est pas pratique pour elle, si ? Je veux dire, ça introduit un conflit dans le dépôt git donc les mises à jour risquent d’être laborieuses.

je vais jeter un oeil aux GenericForeignKeys, merci.

Vayel

Ce n’est pas forcément plus pratique de naviguer de fichier en fichier pour trouver le mixin. Je vois pas forcément de bonnes raisons pour lesquelles le modèle de base de données changerait suffisamment pour créer des problèmes, ou alors c’est que tu t’es totalement trompé sur le but initial et la structure de ton modèle, tout en codant salement. :)

Le rôle que tu fais jouer à ton mixin, c’est le même que pour AUTH_USER_MODEL, sauf qu’il n’est pas utilisé dans les applications externes que tu intègres à ton site donc c’est beaucoup moins justifié.

Si tu veux que l’utilisateur personnalise il y a deux possibilités :

  • soit ton modèle comprends tout et tu active des morceaux par config,
  • soit il va devoir étendre le fonctionnement par du code.

Au niveau du modèle je pense que le code est l’option la plus raisonnable. D’où mon idée pour éviter de spécifier trop fortement le type.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte