As already implied in @gareth's answer, hard-coding a default id
value might not always be the best idea:
If the id
value does not exist in the database, you're in trouble. Even if that specific id
value does exist, the corresponding object may change. In any case, when using a hard-coded id
value, you'd have to resort to things like data-migrations or manual editing of existing database content.
To prevent that, you could use get_or_create() in combination with a unique
field (other than id
).
Here's one way to do it:
from django.db import models
class Exam(models.Model):
title = models.CharField(max_length=255, unique=True)
description = models.CharField(max_length=255)
@classmethod
def get_default_pk(cls):
exam, created = cls.objects.get_or_create(
title='default exam',
defaults=dict(description='this is not an exam'),
)
return exam.pk
class Student(models.Model):
exam_taken = models.ForeignKey(
to=Exam, on_delete=models.CASCADE, default=Exam.get_default_pk
)
Here an Exam.title
field is used to get a unique object, and an Exam.description
field illustrates how we can use the defaults
argument (for get_or_create
) to fully specify the default Exam
object.
Note that we return a pk
, as suggested by the docs:
For fields like ForeignKey
that map to model instances, defaults should be the value of the field they reference (pk
unless to_field
is set) instead of model instances.
Also note that default
callables are evaluated in Model.__init__()
(source). So, if your default value depends on another field of the same model, or on the request context, or on the state of the client-side form, you should probably look elsewhere.