0

Parfois, un champ ForeignKey a besoin d'une valeur par défaut. Par exemple:Quelle est la meilleure façon de gérer les valeurs par défaut du champ du modèle django?

class ReleaseManager(BaseManager): 

    def default(self): 
     return self.filter(default=True).order_by('-modified').first() 


class Release(BaseModel): 
    default = models.BooleanField(default=False) 
    ... 


class Server(models.Model): 
    ... 
    release = models.ForeignKey(Release, null=True, default=Release.objects.default) 

Tout est bien et bon avec le code ci-dessus jusqu'au moment de la migration db après quoi la valeur par défaut fonctionnelle provoque de gros problèmes parce que la fonction par défaut ne peut pas être sérialisé. La migration manuelle peut fonctionner autour de cela, mais sur un grand projet où les migrations sont peut-être squashed périodiquement cela laisse une bombe à retardement pour les imprudents. Une solution de contournement consiste à déplacer la valeur par défaut du champ à la méthode de sauvegarde du modèle, mais cela crée une confusion si le modèle est utilisé par rest framework ou dans la création de formulaires où la valeur par défaut est attendue sur le champ.

Répondre

0

Ma solution de travail préférée actuelle fonctionne avec les migrations et avec le reste de la structure et la génération de formulaires. Il suppose que le gestionnaire d'objets fournit une méthode par défaut et utilise un champ ForeignKey spécialisé pour nous mettre au travail:

class ForeignKeyWithObjectManagerDefault(models.ForeignKey): 

    def __init__(self, to, **kwargs): 
     super().__init__(to, **kwargs) 
     self.to = to 

    def get_default(self): 
     return self.to.objects.default().pk 


class Project(SOSAdminObject): 
    primary = ForeignKeyWithObjectManagerDefault(Primary, related_name='projects') 
    ... 

Maintenant migrations fonctionnent comme prévu et nous pouvons utiliser toutes les fonctionnalités que nous aimons fournir un objet par défaut à un champ de clé étrangère .