Comment puis-je définir une valeur par défaut sur un champ ForeignKey dans un modèle Django ou AdminModel?
Quelque chose comme ça (mais bien sur ça ne marche pas) ...
created_by = models.ForeignKey(User, default=request.user)
Je sais que je peux «tromper» dans la vue, mais en ce qui concerne AdminModel, cela ne semble pas possible.
class Foo(models.Model):
a = models.CharField(max_length=42)
class Bar(models.Model):
b = models.CharField(max_length=42)
a = models.ForeignKey(Foo, default=lambda: Foo.objects.get(id=1) )
Voici une solution qui fonctionnera dans Django 1.7. Au lieu de fournir la valeur par défaut à la définition du champ, définissez-la comme pouvant être annulée, mais remplacez la fonction 'save' pour la remplir pour la première fois (tant qu'elle est nulle):
class Foo(models.Model):
a = models.CharField(max_length=42)
class Bar(models.Model):
b = models.CharField(max_length=42)
a = models.ForeignKey(Foo, null=True)
def save(self, *args, **kwargs):
if self.a is None: # Set default reference
self.a = Foo.objects.get(id=1)
super(Bar, self).save(*args, **kwargs)
Pour Django 1.7 ou supérieur,
Créez simplement un objet ForeignKey et enregistrez-le. La valeur "default" peut être l'id de l'objet à lier par défaut.
Par exemple,
created_by = models.ForeignKey(User, default=1)
Si vous utilisez la version de développement de Django, vous pouvez implémenter la méthode formfield_for_foreignkey()
sur votre AdminModel
pour définir une valeur par défaut.
J'ai fait la même chose que @o_c, mais je préférerais utiliser get_or_create
plutôt que simplement pk
.
class UserSettings(models.Model):
name = models.CharField(max_length=64, unique=True)
# ... some other fields
@staticmethod
def get_default_user_settings():
user_settings, created = UserSettings.objects.get_or_create(
name = 'Default settings'
)
return user_settings
class SiteUser(...):
# ... some other fields
user_settings = models.ForeignKey(
to=UserSettings,
on_delete=models.SET_NULL,
null=True
)
def save(self, *args, **kwargs):
if self.user_settings is None:
self.user_settings = UserSettings.get_default_params()
super(SiteUser, self).save(*args, **kwargs)
def get_user_default_id():
return 1
created_by = models.ForeignKey(User, default=get_user_default_id)
Quant à moi, pour Django 1.7 son travail, juste pk:
category = models.ForeignKey(Category, editable=False, default=1)
mais rappelez-vous que la migration ressemble à
migrations.AlterField(
model_name='item',
name='category',
field=models.ForeignKey(default=1, editable=False, to='item.Category'),
preserve_default=True,
),
donc, je ne pense pas que cela fonctionne avec un utilisateur dynamique pk.
Pour Django> = 1.7, vous pouvez définir la valeur par défaut pour un champ ForeignKey de deux manières différentes:
1) directement sous forme d'entier
DEFAULT_CREATED_BY_USER = 42
class MyModel(Model):
created_by = models.ForeignKey(User, default=DEFAULT_CREATED_BY_USER)
2) En tant qu'appel non lambda renvoyant un entier
Vous pouvez également utiliser un appelable pouvant être résolu en un chemin de module complet. Cela signifie que lambdas ne fonctionne pas. Mais cela va:
def default_created_by_user():
return 42
class MyModel(Model):
created_by = models.ForeignKey(User, default=default_created_by_user)
Références:
Ceci est une légère modification de la réponse de o_c . Cela devrait vous sauver un coup sur la base de données. Notez que dans la méthode save, j'utilise self.a_id = 1 au lieu de self.a = Foo.objects.get (id = 1). Cela a le même effet sans avoir à interroger Foo.
class Foo(models.Model):
a = models.CharField(max_length=42)
class Bar(models.Model):
b = models.CharField(max_length=42)
a = models.ForeignKey(Foo, null=True)
def save(self, *args, **kwargs):
if self.a is None: # Set default reference
self.a_id = 1
super(Bar, self).save(*args, **kwargs)
Au lieu de la fonction lambda, utilisez une fonction partielle. La fonction Lambda n’est pas une sérialisation et donne donc une erreur dans les migrations.
class Foo(models.Model):
a = models.CharField(max_length=42)
class Bar(models.Model):
b = models.CharField(max_length=42)
a = models.ForeignKey(Foo, default=partial(Foo.objects.get, id=1 ))
Vous devez avoir les paramètres liés à setting.AUTH_USER_MODEL dans le fichier settings.py.
Vous pouvez regarder dans le document ci-dessous:
" https://docs.djangoproject.com/fr/1.10/topics/auth/customizing/#substituting-a-custom-user-model "
Vous pouvez remplacer la méthode get_form de votre administrateur de modèle.
admin.py
class YourModelAdmin(admin.ModelAdmin):
def get_form(self, request, obj=None, **kwargs):
form = super(YourModelAdmin, self).get_form(request, obj, **kwargs)
form.base_fields['created_by'].initial = request.user
return form
admin.site.register(YourModel, YourModelAdmin)