Я читаю книгу о Джанго и пытаюсь переосмыслить некоторый контент.(Я использую Django 2.1 и Python 3.6). В книге различные типы контента связаны с модулем, например:
class Module(models.Model):
course = models.ForeignKey(Course,
related_name='modules',
on_delete=models.CASCADE)
title = models.CharField(max_length=200)
description = models.TextField(blank=True)
order = OrderField(blank=True, for_fields=['course'])
class Meta:
ordering = ['order']
def __str__(self):
return '{}. {}'.format(self.order, self.title)
class Content(models.Model):
module = models.ForeignKey(Module,
related_name='contents',
on_delete=models.CASCADE)
content_type = models.ForeignKey(ContentType,
on_delete=models.CASCADE,
limit_choices_to={'model__in': (
'text',
'video',
'image',
'file')})
object_id = models.PositiveIntegerField()
item = GenericForeignKey('content_type', 'object_id')
order = OrderField(blank=True, for_fields=['module'])
class Meta:
ordering = ['order']
class ItemBase(models.Model):
owner = models.ForeignKey(User,
related_name='%(class)s_related',
on_delete=models.CASCADE)
title = models.CharField(max_length=250)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
def __str__(self):
return self.title
def render(self):
return render_to_string(
'courses/content/{}.html'.format(self._meta.model_name),
{'item': self})
class Text(ItemBase):
content = models.TextField()
class File(ItemBase):
file = models.FileField(upload_to='files')
class Image(ItemBase):
file = models.FileField(upload_to='images')
class Video(ItemBase):
url = models.URLField()
В книге есть CBV для создания правильной формы для типов контента.:
class ContentCreateUpdateView(TemplateResponseMixin, View):
module = None
model = None
obj = None
template_name = 'courses/manage/content/form.html'
def get_model(self, model_name):
if model_name in ['text', 'video', 'image', 'file']:
return apps.get_model(app_label='courses',
model_name=model_name)
return None
def get_form(self, model, *args, **kwargs):
Form = modelform_factory(model, exclude=['owner',
'order',
'created',
'updated'])
return Form(*args, **kwargs)
def dispatch(self, request, module_id, model_name, id=None):
self.module = get_object_or_404(Module,
id=module_id,
course__owner=request.user)
self.model = self.get_model(model_name)
if id:
self.obj = get_object_or_404(self.model,
id=id,
owner=request.user)
return super(ContentCreateUpdateView,
self).dispatch(request, module_id, model_name, id)
def get(self, request, module_id, model_name, id=None):
form = self.get_form(self.model, instance=self.obj)
return self.render_to_response({'form': form,
'object': self.obj})
def post(self, request, module_id, model_name, id=None):
form = self.get_form(self.model,
instance=self.obj,
data=request.POST,
files=request.FILES)
if form.is_valid():
obj = form.save(commit=False)
obj.owner = request.user
obj.save()
if not id:
# new content
Content.objects.create(module=self.module,
item=obj)
return redirect('module_content_list', self.module.id)
return self.render_to_response({'form': form,
'object': self.obj})
И содержимое предоставляется пользователями со специальными разрешениями.Хорошо, и теперь вопрос: я хочу, чтобы содержимое управлялось только администратором на сайте администратора.Я пробовал таким образом:
class ContentInline(GenericStackedInline):
model = Content
extra = 0
@admin.register(Module)
class ModuleAdmin(admin.ModelAdmin):
list_display = ['title', 'order', 'course']
list_filter = ['course']
search_fields = ['title', 'description']
inlines = [ContentInline]
@admin.register(Content)
class ContentAdmin(admin.ModelAdmin):
list_display = ['object_id', 'module', 'content_type', 'order']
, но я не смог отобразить в поле администратора сайта поле для загрузки нужного типа контента.Страница модуля выглядит следующим образом:
страница модуля на сайте администратора
В то время как страница содержимого это:
страница содержимого на сайте администратора
Я какое-то время искал решение, но не смог найти.Здесь есть похожая тема: ссылка , но предлагаемые решения предполагают использование javascript и / или дополнительных пакетов, хотя я бы хотел сделать это только с Python и Django.Я также читал, что возможное решение для отображения пользовательских представлений на сайте администратора состоит в том, чтобы написать представление и затем добавить его в URL-адреса администратора, а затем добавить его в модель администратора.Кто-то еще предложил использовать CBV из книги и использовать его в модели администратора.Я попытался реализовать эти предложения без удачи.В последней версии моего кода я пытаюсь использовать CBV с as_view()
следующим образом (в views.py сразу после CBV):
content_create_update_view = ContentCreateUpdateView.as_view()
, а затем в admin.py:
@admin.register(Content)
class ContentAdmin(admin.ModelAdmin):
list_display = ['object_id', 'module', 'content_type', 'order']
def get_urls(self):
urls = super().get_urls()
my_urls = [
path('content/<int:object_id>/change/', self.admin_site.admin_view(content_create_update_view)),
]
return my_urls + urls
любая помощь или предложение с благодарностью.