0

So I am simply trying to add LectureCategory in my Lecture model, I want the user to be only able to select between Classes or Seminars. If I put choices in both models, I can see them on django admin, but I get the error:

Cannot assign "'0'": "Lecture.lecture_category" must be a "LectureCategory" instance.

If I dont put choices in second model, then in admin panel will show 0 or 1, instead of my values. Any suggestion ?

class LectureCategory(models.Model):
    lecture_category = models.IntegerField(choices=((0, "Classes "),
                                                    (1, "Seminars"),
                                                    ))

    def __str__(self):
        return str(self.lecture_category)


class Lecture(models.Model):
    course = models.ForeignKey('Course', on_delete=models.CASCADE, default='', related_name='lectures', null=True, )
    lecture_category = models.ForeignKey('LectureCategory', on_delete=models.CASCADE,
                                         default='', related_name='categories',
                                         choices=((0, "Classes "),
                                                  (1, "Seminars"),
                                                  )
                                         )
7
  • Why is LectureCategory a separate model? There doesn't seem to be any reason for that, especially as it's just storing two integers. Commented Jan 19, 2018 at 11:52
  • I want to iterate them in my template Commented Jan 19, 2018 at 11:53
  • Fine, but that doesn't explain why they need to be in a separate model. Commented Jan 19, 2018 at 11:53
  • I need so that if I have Class, all lectures in the class to be displayed, otherwise if I have a Seminar, all lectures from seminars to be displayed. Commented Jan 19, 2018 at 11:56
  • 1
    LectureCategory shows up in the admin panel as 0 or 1 because that's how you defined LectureCategory instances to be printed (see LectureCategory.__str__) Commented Jan 19, 2018 at 11:58

2 Answers 2

1

You definitly don't need a LectureCategory model to filter Lecture queryeset on a category:

class Lecture(models.Model):
    course = models.ForeignKey(
       'Course', 
        on_delete=models.CASCADE, 
        default=None, 
        related_name='lectures', 
        null=True, 
        )

    CATEGORY_CLASSES = 0
    CATEGORY_SEMINARS = 1
    CATEGORY_CHOICES = (
        (CATEGORY_CLASSES, "Classes"),
        (CATEGORY_SEMINARS, "Seminars"),
        )
    category = models.IntegerField(
       choices=CATEGORY_CHOICES
       )


# select only classes
Lecture.objects.filter(category=Lecture.CATEGORY_CLASSES)

# select only seminars
Lecture.objects.filter(category=Lecture.CATEGORY_SEMINARS)

# display the lecture's category readable label
# cf https://docs.djangoproject.com/en/2.0/ref/models/instances/#django.db.models.Model.get_FOO_display
print(lecture.get_category_display())

Also you can use custom managers here to directly have Lecture.seminars.all() and Lecture.classes.all()

Having a distinct LectureCategory model makes sense if you want to allow admins to add new categories, but then you will loose custom managers per category and actually anything that requires categories to be known in advance. In this case your LectureCategory model will need some label field:

class LectureCategory(models.Model):
    label = models.CharField(
        "label",
         max_length=50
         )
    def __str__(self):
        return self.label


class Lecture(models.Model):
    course = models.ForeignKey(
       'Course', 
        on_delete=models.CASCADE, 
        default=None, 
        related_name='lectures', 
        null=True, 
        )

    category = models.ForeignKey(
        LectureCategory, 
        related_name="lectures"
        on_delete=models.PROTECT, 
        )

Then if you want to iterate on categories/lectures:

for category in Category.objects.all():
    print(category)
    for lecture in category.lectures.all():
        print(lecture)
Sign up to request clarification or add additional context in comments.

Comments

0

you don't need a separate model for category until you want to add more information regarding categories. you can simply do this like

class Lecture(models.Model):
    Classes= 0
    Seminars= 1
    lecture_choice = (
        (Classes, 'Classes'),
        (Seminars, 'Seminars'),
    )
    course = models.ForeignKey('Course', on_delete=models.CASCADE, default='', related_name='lectures', null=True, )
    lecture_category = models.IntegerField(choices=lecture_choice ,default=Classes)

2 Comments

Now when I iterrate I get only 0 and 1 on my template.
if you want to display values of choices then use {{ object.get_lecture_category_display }}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.