methuselah
methuselah

Reputation: 13206

Reference two foreign keys in Django data model

I want to reference two foreign keys in the Conversation model, because user_one and user_two can be a Person or Business either way. What is the best way of expressing this?

class Person(models.Model):
    """
    Person model
    """
    id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
    avatar = models.ImageField(upload_to=get_upload_avatar_path, blank=True, null=True, default=None, max_length=255)
    first_name = models.CharField(max_length=255)
    last_name = models.CharField(max_length=255)


class Business(models.Model):
    """
    Business model
`   """
    id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
    name = models.CharField(max_length=255, null=True, default=None)


class Conversation(models.Model):
    """
    Conversation model
    Contains conversation relational data between registered users
    """
    id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
    #user_one = models.ForeignKey(Person, null=True, default=None)
    #user_two = models.ForeignKey(Business, null=True, default=None)


class ConversationReply(models.Model):
    """
    Conversation reply model
    Contains conversation reply data
    """
    id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
    date_time = models.DateTimeField(blank=True, null=True, default=None)
    conversation = models.ForeignKey(Conversation, null=True, default=None)
    reply = models.CharField(max_length=255)

Upvotes: 1

Views: 119

Answers (1)

Gustavo Reyes
Gustavo Reyes

Reputation: 1334

I would probably use django model inheratance and create an Entity model.

 class Entity(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid4, editable=False)

    class Meta:
         abstract = True

 class Person(Entity):
    """
    Person model
    """

    avatar = models.ImageField(upload_to=get_upload_avatar_path, blank=True, null=True, default=None, max_length=255)
    first_name = models.CharField(max_length=255)
    last_name = models.CharField(max_length=255)


class Business(Entity):
    """
    Business model
`   """
    name = models.CharField(max_length=255, null=True, default=None)


class Conversation(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
    content_object_1 = GenericForeignKey('content_type', 'object_1_id')
    content_object_2 = GenericForeignKey('content_type', 'object_2_id')

Note that due to the use of GenericForeignKey filtering will not work the traditional way. Then you'll be able to do something like this:

from django.contrib.contenttypes.models import ContentType

contenttype_obj = ContentType.objects.get_for_model(person_object)

Conversation.objects.filter(object_id_1=person_object.id, content_type=contenttype_obj)

Upvotes: 1

Related Questions