How to create several ContentType fields in a Django model?

239 views Asked by At

My Django model uses a Function model, i.e. a generic function in the company (e.g. : CFO).

In this model, I would like to have a field pointing to the default person who holds the function + another field pointing to a backup person in case of problem. Each of this field should be able to point to various models (both the user model + a model with people who have not signed in yet on the website)

As long as I only point to one model, it is easy :

class Function(models.Model):
    function_name = models.CharField(max_length=255, blank=True)  # e.g. CFO
    main_user = models.ForeignKey('auth.User', on_delete=models.SET_NULL, null=True, blank=True)
    backup_user = models.ForeignKey('auth.User', on_delete=models.SET_NULL, null=True, blank=True)

But if I want each of the two fields to point to different models, I need to use ContentType, like :

class Function(models.Model):
    functionname = models.CharField(max_length=255, blank=True)  # e.g. CFO
    
    #GenericForeignKey:
    content_type = models.ForeignKey(ContentType, on_delete=models.SET_NULL)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey()

How to have two GenericForeignKeys in one model ? (for the main_user and for the backup_user)?

Thanks a lot for you help, I am confused on how to proceed

1

There are 1 answers

0
GwynBleidD On

GenericForeginKey can take 2 positional arguments, first of them is the field name for the ForeignKey to the ContentType, second one is the field name for the object ID for the generic relation. Given that information, you can construct your generic relations like:

class Function(models.Model):
    functionname = models.CharField(max_length=255, blank=True)  # e.g. CFO

    main_user_content_type = models.ForeignKey(ContentType, on_delete=models.SET_NULL)
    main_user_object_id = models.PositiveIntegerField()
    main_user = GenericForeignKey('main_user_content_type', 'main_user_object_id')

    backup_user_content_type = models.ForeignKey(ContentType, on_delete=models.SET_NULL)
    backup_user_object_id = models.PositiveIntegerField()
    backup_user = GenericForeignKey('backup_user_content_type', 'backup_user_object_id')