Reputation:
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
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
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