ситуация
В моем примере я хочу создать модель страницы с отношением «многие ко многим» с моделью блоков контента.
- Страница имеет заголовок, слаг и блок основного содержимого.
- блоки контента имеют заголовок и блок контента.
Что я могу получить:
Отображение страниц.блоков в форме администратора отображает множественный выбор блоков контента
При создании встроенной формы для блоков контента на странице администратор показывает несколько вариантов выбора со знаком +, чтобы добавить больше
Что я пытаюсь сделать:
Полный CRUD для блока контента на странице admin
Примечание: Из-за сложности моего запроса я начинаю верить, что шаблон UX, который я пытаюсь выполнить, неверен. Если я хочу, чтобы создатель контента пришел и создал страницу, выберите несколько существующих блоков контента (например, существующий блок контента боковой панели), а затем создайте новый пользовательский блок. Я не думаю, что я хочу, чтобы он прыгал повсюду, чтобы сделать это ...
Вопрос по теме без решений:
Как использовать TabularInline с редактируемыми полями в отношении ManyToMany?
EDIT
my admin.py</p>
<pre><code>from django.contrib import admin
from django.contrib.flatpages.admin import FlatpageForm, FlatPageAdmin
from django.contrib.flatpages.models import FlatPage
from my_flatpages.models import ExtendedFlatPage, ContentBlock
from mptt.admin import MPTTModelAdmin
from django import forms
import settings
"""
Extended Flatpage Form
"""
class ExtendedFlatPageForm(FlatpageForm):
class Meta:
model = ExtendedFlatPage
"""
Page Content Block inline form
"""
class ContentBlockInlineAdminForm(forms.ModelForm):
# Add form field for selecting an existing content block
content_block_choices = [('', 'New...')]
content_block_choices.extend([(c.id, c) for c in ContentBlock.objects.all()])
content_blocks = forms.ChoiceField(choices=content_block_choices, label='Content Block')
def __init(self, *args, **kwargs):
super(ContentBlockInlineAdminForm, self).__init__(*args, **kwargs)
# Show as existing content block if it already exists
if self.instance.pk:
self.fields['content_block'].initial = self.instance.pk
self.fields['title'].initial = ''
self.fields['content'].initial = ''
# Make title and content not required so user can opt to select existing content block
self.fields['title'].required = False
self.fields['content'].required = False
def clean(self):
content_block = self.cleaned_data.get('content_block')
title = self.cleaned_data.get('title')
content = self.cleaned_data.get('content')
# Validate that either user has selected existing content block or entered info for new content block
if not content_block and not title and not content:
raise forms.ValidationError('You must either select an existing content block or enter the title and content for a new content block')
"""
Content Block Inline Admin
"""
class ContentBlockInlineAdmin(admin.TabularInline):
form = ContentBlockInlineAdminForm
class Meta:
model = ContentBlock
extra = 1
"""
Extended Flatpage Admin
"""
class ExtendedFlatPageAdmin(FlatPageAdmin, MPTTModelAdmin):
form = ExtendedFlatPageForm
fieldsets = (
(
None,
{
'fields': ('url', 'title', 'content', ('parent', 'sites'))
}
),
(
'SEO Fields',
{
'fields': ('seo_title', 'seo_keywords', 'seo_description'),
'classes': ('collapse', )
}
),
(
'Advanced options',
{
'fields': ('enable_comments', 'registration_required', 'template_name'),
'classes': ('collapse', )
}
),
)
inlines = (ContentBlockInlineAdmin,)
class Media:
js = (
'https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js',
settings.MEDIA_URL + 'js/tinymce/jquery.tinymce.js',
settings.MEDIA_URL + 'js/init_tinymce.js'
)
admin.site.unregister(FlatPage)
admin.site.register(ExtendedFlatPage, ExtendedFlatPageAdmin)