I'm adding something on top of @djvg answer and providing some illustration to @Super Kai one's concerning the class method way of solving this problem:
Using a class method is also useful in this case, and probably in a lot of other cases, because you may have to add other ForeignKey relationships to your model later on like so:
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
)
# NEW
class Teacher(models.Model):
exam_given = models.ForeignKey(
to=Exam, on_delete=models.CASCADE, default=Exam.get_default_pk
)
In my case, I came here to figure out how to provide a default image to a Photo model whom I wanted to be used by several other models that would also use that default image like so:
class Photo(models.Model):
title = models.CharField(max_length=200, unique=True)
image = models.ImageField(upload_to='photos',
default="default_photo_folder/default_image")
@classmethod
def get_or_create_default_photo_pk(cls):
obj, created_bool = cls.objects.get_or_create(
title='default photo', # ↓ title value will be automatically included in defaults ↓
defaults=dict(image="default_photo_folder/default_image"),
)
return obj.pk
------------------------------------------------------------------
# From photoapp.models import Photo
class Event(models.Model):
photo = models.ForeignKey(Photo,
on_delete=models.SET_DEFAULT,
related_name='event_photos',
default=Photo.get_or_create_default_photo_pk)
class Place(models.Model):
photo = models.ForeignKey(Photo,
on_delete=models.SET_DEFAULT,
related_name='place_photos',
default=Photo.get_or_create_default_photo_pk)
Please note that in this example I already have a default photo in my media/default_photo folder. I also used models.SET_DEFAULT to set my default photo as the object's photo when its original photo would be deleted. As stated in the doc, I also used a unique field lookup in my get_or_create() method to avoid extra headache .
default=get_exam()
will callget_exam
immediately and store the value permanently, whereasdefault=get_exam
stores the method which would later be called each time thedefault
attribute is used, to get the value at that moment. It's often used with datetime, i.e.default=datetime.now
, notdefault=datetime.now()
. – Figurationdefault=get_exam()
anddefault=get_exam
effectively is the same, unless you can re-call default? – Malinadefault
as to me it reads as something that should be relatively static, thanks it's been interesting and thought provoking for me at least :) – Malina