我有一个带有以下的django 1.6应用程序(为了清晰起见而修剪) 课程定义。用户是标准的django.contrib.auth用户类。
class Event(models.Model):
user = models.ForeignKey(User, related_name='events')
name = models.CharField(max_length=64)
class Profile(models.Model):
user = models.ForeignKey(User, related_name='aprofile')
class MemberProfile(Profile):
pass
以下是我的管理类:
class ProfileAdmin(ModelAdmin):
model = Profile
fields = ('user', )
class MemberProfileAdmin(ModelAdmin):
model = MemberProfile
fields = ('user', )
readonly_fields = ('user', )
我想要做的是显示给定成员或至少个人资料的所有事件的只读列表。当然,加入用户外键似乎是要走的路,但我想知道如何实现这一目标。以下是迄今为止的尝试摘要。
在Event类上直接引用用户字段定义内联管理员,并将其添加到ProfileAdmin:
class EventInlineAdmin(TabularInline):
model = Event
fk_name = 'user' # Fails - fk_name 'user' is not a ForeignKey to <class 'solo365.solo_profile.models.profile.Profile'>
......好吧,不,肯定不是。但我们的用户有一个'aprofile'字段,所以......
class EventInlineAdmin(TabularInline):
model = Event
fk_name = 'user__aprofile' # Fails - EventInlineAdmin.fk_name' refers to field 'user__aprofile' that is missing from model 'admin_fk_test.Event'.
好的,这些字段看起来应该同步,但也许我们需要更积极一些:
class EventInlineAdmin(TabularInline):
model = Event
fk_name = 'user__aprofile__pk' # Fails - 'EventInlineAdmin.fk_name' refers to field 'user__aprofile__pk' that is missing from model 'admin_fk_test.Event'.
我也尝试在内联模型和常规模型管理员中弄乱formfield_for_foreignkey()和朋友,但如果fk_name没有有效值,那么这些方法永远不会被调用。
然后我考虑直接从个人资料的用户访问事件字段:
class ProfileAdmin(ModelAdmin):
model = Profile
fields = ('user', 'user__events') # Fails - Unknown field(s) (user__events) specified for Profile. Check fields/fieldsets/exclude attributes of class ProfileAdmin.
使用自定义formfield_for_foreignkey()方法怎么样?可悲的是,除了“用户”字段之外,永远不会要求任何其他内容。我还考虑过一个自定义的get_formsets()方法,但坦率地说,如果没有一个有效的EventInlineAdmin,我不知道如何使用它。
我当然可以定义一个自定义字段,它简单地连接所有事件并将其作为字符串返回,但理想情况下我更喜欢像全功能内联(甚至是只读)之类的东西,而不仅仅是一个块文本。 IOW这样的自定义字段将有一个方法(理想情况下)将返回内联表单,而不需要任何类型的自定义模板,allow_tags的设置等。
我注定要为Profile管理员类创建一个完全自定义的表单吗?或者有一种简单的方法来完成我正在尝试做的事情,我只是想念它?
更新
如果提供的解决方案适用于MemberProfileAdmin类,而不仅仅是ProfileAdmin类,则会获得积分。
答案 0 :(得分:2)
User
和Profile
之间的关系应该是1:1
关系,允许通过user__aprofile
进行引用。否则,foreing键的反向关系是一个查询集,因为一个外键可以分配给多个实例。这可能是您的代码失败的原因。
将其更改为:
class Profile(models.Model):
user = models.OneToOneKey(User, related_name='aprofile')
这有点像使用ForeignKey(unique=True)
。
要了解属性,可能有助于在有问题的模型实例上调用dir(model_instance)
,或者在Django shell(./manage.py shell
)中尝试。
此外,我已经体验到,在您的情况下分配自定义related_name
可能更令人困惑,您可以通过查看相关名称来查看一个配置文件,但实际上您将获得一个查询集。
在这种情况下生成的名称为profile_set
,您必须致电profile_set.all()
或profile_set.values()
以获取一些实际的个人资料。