Définition de la valeur par défaut pour l’atsortingbut Clé étrangère

Quelle est la meilleure façon de définir une valeur par défaut pour un champ de clé étrangère dans un modèle? Supposons que je dispose de deux modèles, Student et Exam avec un étudiant ayant passé l’examen_en tant que clé étrangère. Comment définirais-je idéalement une valeur par défaut? Voici un journal de mes efforts

class Student(models.Model): .... ..... exam_taken = models.ForeignKey("Exam", default=1) 

Fonctionne, mais ayez une intuition, il y a une meilleure façon.

 def get_exam(): return Exam.objects.get(id=1) class Student(models.Model): .... ..... exam_taken = models.ForeignKey("Exam", default=get_exam) 

A partir de là , mais échoue avec les tables, il n’existe pas d’erreur lors de la synchronisation.

Toute aide serait appréciée.

Dans vos deux exemples, vous codez en dur l’id de l’instance par défaut. Si c’est inévitable, je définirais juste une constante.

 DEFAULT_EXAM_ID = 1 class Student(models.Model): ... exam_taken = models.ForeignKey("Exam", default=DEFAULT_EXAM_ID) 

Moins de code et le nom de la constante le rendent plus lisible.

J’utilise des clés naturelles pour adopter une approche plus naturelle:

/models.py

 from django.db import models class CountryManager(models.Manager): """Enable fixtures using self.sigla instead of `id`""" def get_by_natural_key(self, sigla): return self.get(sigla=sigla) class Country(models.Model): objects = CountryManager() sigla = models.CharField(max_length=5, unique=True) def __unicode__(self): return u'%s' % self.sigla class City(models.Model): nome = models.CharField(max_length=64, unique=True) nation = models.ForeignKey(Country, default='IT') 

Vous pouvez utiliser ce modèle:

 class Other(models.Model): DEFAULT_PK=1 name=models.CharField(max_length=1024) class FooModel(models.Model): other=models.ForeignKey(Other, default=Other.DEFAULT_PK) 

Bien sûr, vous devez vous assurer qu’il y a une ligne dans la table de Other . Vous devez utiliser une migration de données pour vous assurer qu’elle existe.

Dans mon cas, je voulais définir la valeur par défaut sur toute instance existante du modèle associé. Comme il est possible que l’ Exam avec l’ID 1 ait été supprimé, j’ai effectué les opérations suivantes:

 class Student(models.Model): exam_taken = models.ForeignKey("Exam", blank=True) def save(self, *args, **kwargs): try: self.exam_taken except: self.exam_taken = Exam.objects.first() super().save(*args, **kwargs) 

Si exam_taken n’existe pas, django.db.models.fields.related_descriptors.RelatedObjectDoesNotExist sera django.db.models.fields.related_descriptors.RelatedObjectDoesNotExist lors d’une tentative d’access.

Je modifierais légèrement la réponse de @ vault ci-dessus (cela peut être une nouvelle fonctionnalité). Il est certainement souhaitable de se référer au champ par un nom naturel. Cependant, au lieu de remplacer le Manager j’utiliserais simplement le to_field de ForeignKey :

 class Country(models.Model): sigla = models.CharField(max_length=5, unique=True) def __unicode__(self): return u'%s' % self.sigla class City(models.Model): nome = models.CharField(max_length=64, unique=True) nation = models.ForeignKey(Country, to_field='sigla', default='IT')