Jack
Jack

Reputation: 470

Should I use Many-to-one relationship or a Many-to-many?

Basically I am creating a website using django where I have created a class called courses and a separate class Class. I'm now confused which relationship I should use.

My code:

class Class(models.Model):
    title = models.CharField(max_length=100)
    video = models.FileField(upload_to='class/class_videos',null=True,
validators=[FileExtensionValidator(allowed_extensions=['MOV','avi','mp4','webm','mkv'])])


    def __str__(self):
        return self.name


class Course(models.Model):
    title = models.CharField(max_length=100)
    image = models.ImageField(upload_to='class/instructor_pics', null=True)
    instructor = models.CharField(max_length=100)
    instructor_image = models.ImageField(upload_to='class/instructor_pics', null=True)
    students = models.ManyToManyField(User, related_name='courses_joined', blank=True)
    slug = models.SlugField(max_length=200, unique=True)
    description = models.TextField(max_length=300, null=True)
    created = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-created']

    def __str__(self):
        return self.title

Thanks in advance!

Upvotes: 1

Views: 91

Answers (3)

Jack
Jack

Reputation: 470

Change your code to

class Course(models.Model):
    title = models.CharField(max_length=100)
    image = models.ImageField(upload_to='class/instructor_pics', null=True)
    instructor = models.CharField(max_length=100)
    instructor_image = models.ImageField(upload_to='class/instructor_pics', null=True)
    enrolled_students = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='enrolled_students', blank=True)
    students = models.ManyToManyField(User, related_name='courses_joined', blank=True)

    slug = models.SlugField(max_length=200, unique=True)
    description = models.TextField(max_length=300, null=True)
    created = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-created']

    def __str__(self):
        return self.title


    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)

        img = Image.open(self.image.path)

        if img.height > 285 or img.width > 201:
            output_size = (285, 201)
            img.thumbnail(output_size)
            img.save(self.image.path)

        img2 = Image.open(self.instructor_image.path)

        if img2.height > 40 or img2.width > 40:
            output_size = (40, 40)
            img2.thumbnail(output_size)
            img2.save(self.instructor_image.path)



class Class(models.Model):
    title = models.CharField(max_length=100)
    video = models.FileField(upload_to='class/class_videos',null=True,
validators=[FileExtensionValidator(allowed_extensions=['MOV','avi','mp4','webm','mkv'])])
    course = models.ForeignKey(Course, on_delete=models.CASCADE, null=True, related_name='classes')


def __str__(self):
    return self.title

Upvotes: 2

Gonçalo Peres
Gonçalo Peres

Reputation: 13622

I reckon that the course will be divided into classes. So, the Class model will contain a ForeignKey field that points to the Course model.

More precisely, this is what OP will want

class Class(models.Model):
    course = models.ForeignKey(Course, related_name='classes', on_delete=models.CASCADE)

Upvotes: 0

Eric Yang
Eric Yang

Reputation: 2750

Thinking about your problem, each Class can only belong to one course, but each course can have multiple classes correct?

If that's the case then you should have a many to one where many is the class and the course is the one.

You already have it somewhat in your code

students = models.ManyToManyField(User, related_name='courses_joined', blank=True)
classes = models.OneToManyField(Class, related_name='...')

Upvotes: 0

Related Questions