在 Django Admin 中将 ManyToManyWidget 添加到 ManyToManyField 的反面
问题描述
假设我在 Django 1.4 中有一个简单的博客应用程序:
Let's say I have a simple blog app in Django 1.4:
class Post(models.Model):
title = …
published_on = …
tags = models.ManyToManyField('Tag')
class Tag(models.Model):
name = …
即一个帖子有很多标签.在 Django 管理员上,如果我在 fields
中为 PostAdmin<包含
tags
,我会得到一个不错的小 <select multi>
/代码>.有没有一种简单的方法可以在 TagAdmin
中包含帖子列表(作为简单的 <select multi>
)?我尝试将 fields = ['name', 'posts']
放入 TagAdmin
并得到 ImproperlyConfigured
错误.(post_set
的结果相同).
i.e. a post has many tags. On the Django admin, I get a nice little <select multi>
if I include tags
in the fields
for the PostAdmin
. Is there an easy way to include the list of the posts (as a simple <select multi>
) in the TagAdmin
? I tried putting fields = ['name', 'posts']
in the TagAdmin
and got an ImproperlyConfigured
error. (same result for post_set
).
我对 Django 没问题,所以可以创建一个适当的 AdminForm 和 Admin 对象,但我希望有一个 Right Way™ 来做.
I'm alright with Django, so could whip up a proper AdminForm and Admin object, but I'm hoping there a Right Way™ to do it.
解决方案
这可以通过自定义表单来实现.
This is possible to do with a custom form.
from django.contrib import admin
from django import forms
from models import Post, Tag
class PostAdminForm(forms.ModelForm):
tags = forms.ModelMultipleChoiceField(
Tag.objects.all(),
widget=admin.widgets.FilteredSelectMultiple('Tags', False),
required=False,
)
def __init__(self, *args, **kwargs):
super(PostAdminForm, self).__init__(*args, **kwargs)
if self.instance.pk:
self.initial['tags'] = self.instance.tags.values_list('pk', flat=True)
def save(self, *args, **kwargs):
instance = super(PostAdminForm, self).save(*args, **kwargs)
if instance.pk:
instance.tags.clear()
instance.tags.add(*self.cleaned_data['tags'])
return instance
class PostAdmin(admin.ModelAdmin):
form = PostAdminForm
admin.site.register(Post, PostAdmin)
如果您想要垂直堆叠的小部件,可以将其中的 False
替换为 True
.
That False
in there can be replaced with a True
if you want vertically stacked widget.
相关文章