Django管理界面中的ManyToManyField

38

我做了一个模型(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'.

我想在更改用户页面上显示类似于的操作测试。我该怎么做?


1
如果下面的答案回答了您的问题,请您打勾确认。如果没有回答您的问题,请告诉我们您还需要什么帮助,我们会尽力协助。 - victorhooi
1个回答

81

嗯,我认为你不想在这里使用内联元素。

你应该使用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。

UserProfile 包含到 opetest 的 m2m 关系 - 我们在管理界面中使用 filter_horizontal 进行展示。最终结果类似于这样:

Opetest with 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)

如果你有任何问题或需要进一步的帮助,请告诉我。


嗯,为什么不在UserProfile上创建opetest字段,并将其映射到opetest?它是一个m2m字段,所以关系的哪一端并不重要 - 然后你就可以在opetest字段上使用filter_horizontal了。 - victorhooi
所以,我已经添加了字段,但它不起作用:'class ProfileAdmin(UserAdmin):' 'usertests = models.ManyToManyField(opetest, blank=True)''ProfileAdmin.filter_horizontal' 指的是模型“User”中缺少的字段“usertests”。 filter_horizontal = ('usertests',) - baobee
嗯,你可以编辑一下你的问题,然后粘贴完整的models.pyadmin.py吗?我有些困惑之前的文本,因为你有一个看起来像是admin.pyclass ProfileAdmin(UserAdmin),但接下来的一行又定义了一个模型字段。如果你粘贴完整的代码,我们可以更容易地帮助你解决问题。 - victorhooi
@baobee:你所说的“on the fly”是什么意思?你是指在运行时动态生成吗?我有点困惑。如果你能贴出你的源代码和你想要实现的目标,我们或许可以提供更多帮助 =)。 - victorhooi
它能在Django管理后台之外使用吗?我想在我创建的一个中间视图中使用它,这个视图从技术上讲不是官方的管理后台视图,我只是在get_urls中添加了URL。 - radtek
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接