user9092892
user9092892

Reputation:

Django cannot assign value, must be another instance

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"),
                                                  )
                                         )

Upvotes: 0

Views: 374

Answers (2)

bruno desthuilliers
bruno desthuilliers

Reputation: 77912

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)

Upvotes: 1

Sumeet Kumar
Sumeet Kumar

Reputation: 1019

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)

Upvotes: 0

Related Questions