Django 管理员多对多字段
Posted
技术标签:
【中文标题】Django 管理员多对多字段【英文标题】:Django Admin ManyToManyField 【发布时间】:2011-12-24 00:56:41 【问题描述】:我已经做了一个模型(models.py):
class opetest(models.Model):
name = models.CharField(max_length=200)
author = models.ForeignKey(User, related_name='author')
description = models.TextField(u'Test description', help_text = u'Some words about quiz')
pub_date = models.DateTimeField('date published', blank=False)
vacancies = models.ManyToManyField(Vacancy, blank=True)
students = models.ManyToManyField(User, blank=True, related_name='opetests') #This field I want to edit on "User change page"
estimate = models.IntegerField(default = 0, help_text = u'Estimate time in hours. \'0\' - unlimited')
然后我尝试添加内联块以允许在“更改用户”页面 (admin.py) 上分配 opetest
:
class ProfileAdmin(UserAdmin):
filter_horizontal = ('opetests',)
admin.site.unregister(User)
admin.site.register(User, ProfileAdmin)
我得到了一个错误:
'ProfileAdmin.filter_horizontal' refers to field 'opetests' that is missing from model 'User'.
我想在 更改用户 页面上显示像 Groups 这样的操作测试。我怎样才能做到这一点?
【问题讨论】:
如果下面的答案回答了您的问题,您可以打勾吗?如果没有,请告诉我们您还需要什么,我们可以尝试提供帮助。 【参考方案1】:嗯,我不认为你想要内联。
您想使用 Django 管理员的 filter_horizontal:
https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.filter_horizontal
class ProfileAdmin(UserAdmin)
filter_horizontal = ('opetest',)
这将为您提供您所描述的小部件,用于在用户更改页面上添加/删除组。
好的,根据您的编辑,更新答案 - 基本上,我们拥有的是一个用户配置文件,链接到每个用户。
UserProfile 包含与 opetest 的 m2m 关系 - 我们在管理员中使用 filter_horizontal 显示。最终结果是这样的:
models.py
from django.db import models
from django.contrib.auth.models import User
class opetest(models.Model):
name = models.CharField(max_length=200)
author = models.ForeignKey(User, related_name='author')
description = models.TextField(u'Test description', help_text = u'Some words about quiz')
pub_date = models.DateTimeField('date published', blank=False)
#vacancies = models.ManyToManyField(Vacancy, blank=True)
students = models.ManyToManyField(User, blank=True, related_name='opetests') #This field I want to edit on "User change page"
estimate = models.IntegerField(default = 0, help_text = u'Estimate time in hours. \'0\' - unlimited')
class UserProfile(models.Model):
user = models.OneToOneField(User, unique=True)
ope = models.ManyToManyField(opetest)
test_flag = models.BooleanField()
admin.py
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
from secondapp.models import UserProfile, opetest
admin.site.unregister(User)
class opetestAdmin(admin.ModelAdmin):
pass
class UserProfileInline(admin.StackedInline):
model = UserProfile
filter_horizontal = ('ope',)
class CustomUserAdmin(UserAdmin):
#filter_horizontal = ('user_permissions', 'groups', 'ope')
save_on_top = True
list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff', 'last_login')
inlines = [UserProfileInline]
admin.site.register(User, CustomUserAdmin)
admin.site.register(opetest, opetestAdmin)
如果您有任何问题或需要任何进一步的信息,请告诉我。
【讨论】:
filter_horizontal 参数应参考模型字段。但这里的 opetest 是一个模型。 嗯,您为什么不在 UserProfile 上创建opetest
字段,并将该映射映射到 opetest
?这是一个 m2m 字段,所以它在关系的哪一端并不重要 - 那么您可以在 opetest
字段上使用 filter_horizontal
吗?
对不起 Victor,你能描述一下,我如何在 UserProfile 上创建字段并将其映射到 opetest?
所以,我添加了字段,但它不起作用:'class ProfileAdmin(UserAdmin):' 'usertests = models.ManyToManyField(opetest, blank=True)' 'ProfileAdmin.filter_horizontal' 指到模型“用户”中缺少的“用户测试”字段。 filter_horizontal = ('usertests',)
嗯,您可以编辑您的问题,并粘贴完整的models.py
和admin.py
吗?我对前面的文本有点困惑,因为你有class ProfileADmin(UserAdmin)
,它看起来像admin.py
,但是在下一行你定义了一个模型字段。如果您粘贴完整代码,我们可以帮助您更轻松地工作。以上是关于Django 管理员多对多字段的主要内容,如果未能解决你的问题,请参考以下文章
在 django admin 中使用 related_name 配置多对多字段