Matt Salzman
Matt Salzman

Reputation: 265

Foreign key to multiple other tables

I am working on a content management system where a user can create a course for a student to go through.

So far my database has Course, Lesson, and Slide models and I want to connect my Slide model to Quiz, HTML, or Video:

class Course(models.Model):
    company = models.ForeignKey(Company, on_delete=models.CASCADE)
    slug = models.SlugField(max_length=40, unique=True)
    name = models.CharField(max_length=100)
    desc = models.CharField(max_length=1000)
    date_created = models.DateTimeField(default=datetime.now, blank=True)
    last_updated = models.DateTimeField(default=datetime.now, blank=True)
    price = models.DecimalField(max_digits=8, decimal_places=2)
    is_visible = models.BooleanField(default=True)

    def __str__ (self):
        return self.name

class Lesson(models.Model):
    course = models.ForeignKey(Course, on_delete=models.CASCADE)
    name = models.CharField(max_length=100)
    order = models.IntegerField()
    def __str__ (self):
        return self.name

class Quiz(models.Model):
    points = models.IntegerField()
    # Link to quiz model

class HTML(models.Model):
    content = models.TextField(blank=True)

class Video(models.Model):
    media_path = models.CharField(max_length=150)


class Slide(models.Model):
    lesson = models.ForeignKey(Lesson, on_delete=models.CASCADE)
    title = models.CharField(max_length=100)
    slide_type = models.CharField(max_length=100, choices=[("video", "Video"),("image", "Image"), ("text", "Text"), ("quiz", "Quiz")])
    notes = models.TextField(blank=True)
    last_updated = models.DateTimeField(default=datetime.now, blank=True)
    content = models.TextField(blank=True)
    reference = models.CharField(max_length=150, blank=True)
    def __str__ (self):
        return self.title



class QuizQuestions(models.Model):
    quiz = models.ForeignKey(Quiz, on_delete=models.CASCADE)
    question = models.TextField()
    points = models.IntegerField()

Now my slide model could be 1 of 3 things:

  1. Text (raw HTML)
  2. Video
  3. Test

How do I design my database slide model so it can either be a link to a Video, HTML, or Quiz?

My thoughts are:

  1. I could create a module path in Slide and the path would be the connecting text would be the connection database and a foreign key to it
  2. Somehow create a foreign key that connects to any of the other database tables

Let me know if you have any better ideas, I would like a solution that is scalable and I am open to new ideas

Upvotes: 0

Views: 72

Answers (1)

2ps
2ps

Reputation: 15966

There are several ways to implement this.

  1. You can do this with a GenericForeignKey
  2. You can also do this with model inheritance by, for example, having a SlideContent model that each of the Text, HTML, and Video models derive from using multi-table inheritance. Then the Slide can have a foreign key to the SlideContent model.

Upvotes: 1

Related Questions