Страницы в стиле блога в Django с различными типами контента. Лучшая структура модели
Я относительно новичок в разработке Django. Я создаю сайт, где есть раздел с учебниками. Допустим, для моего вопроса нужен учебник по Linked List. Поскольку все учебники будут в основном одинаковыми, похоже, что шаблоны будут хорошо работать здесь. Я хочу добиться того, чтобы я мог создавать новые страницы (записи учебников) в панели администратора, с текстовыми полями и так далее (что-то вроде блога, только без актуальности дат, а не содержания учебников). Сложность для меня заключается в том, что в одной обучающей записи может быть разное количество данных разных типов. Например, одна из них может иметь структуру:
- текст
- код
- текст
- изображение
- текст
- код
и еще один:
- текст
- изображение
- код
А если я делаю новую запись, она должна генерироваться с помощью шаблона, как это обычно делается в Django. Я думал о трех способах удовлетворить это динамическое поведение, но я вижу трудности в каждом из них и хотел бы знать, какая практика будет лучшей.
Итак, структура будет похожа на Блог:
class TutorialPost(models.Model):
title = models.CharField(max_length=200, unique=True)
text_content = models.TextField()
code_block = models.TextField()
#....
Проблема здесь в том, что я не знаю, как добиться твоего динамического поведения, поскольку мне может понадобиться больше текстовых полей или блоков кода в другом порядке.
Я также думал о том, чтобы иметь только одно текстовое поле и обрабатывать его как поле markdown. Таким образом, я бы взял пакет markdown, такой как Django MarkdownX, и скомпилировал бы контент text_content. Проблема здесь в том, что у меня гораздо меньше свободы в том, как может выглядеть дизайн, например, блока кода (подсветка синтаксиса, фон и так далее).
Моя последняя идея заключалась в том, чтобы снова иметь только одно поле text_content как вариант ввода, но поместить обычный текст, код, изображения и т.д. в собственные теги (похожие на три акцента, используемые здесь, на stackoverflow) и обработать/парсить их после этого, чтобы представить их в правильном порядке по запросу.
Я с нетерпением жду ответа.
Думаю, вы можете сделать модель для каждого типа контента, например, так.
class TextContent(models.Model):
body = models.TextField()
post = models.ForeignKey(TutorialPost, on_delete=models.CASCADE)
Таким образом, вы можете создать несколько "блоков контента" одного времени в одном посте.
Для заказа можно создать пользовательский OrderField
, вот пример.
from django.core.exceptions import ObjectDoesNotExist
class OrderField(models.PositiveIntegerField):
def __init__(self, for_fields=None, *args, **kwargs):
self.for_fields = for_fields
super().__init__(*args, **kwargs)
def pre_save(self, model_instance, add):
if getattr(model_instance, self.attname) is None:
# No current value
try:
qs = self.model.objects.all()
if self.for_fields:
# Filter by objects with the same field values
# for the fields in 'for_fields'
query = {field: getattr(model_instance, field)\
for field in self.for_fields}
qs = qs.filter(**query)
# Get the order of the last item
last_item = qs.latest(self.attname)
value = last_item.order + 1
except ObjectDoesNotExist:
value = 0
setattr(model_instance, self.attname, value)
return value
else:
return super().pre_save(model_instance, add)