【问题标题】:Django: Show filter_horizontal on 'User Change' admin pageDjango:在“用户更改”管理页面上显示 filter_horizo​​ntal
【发布时间】:2013-01-27 12:01:05
【问题描述】:

我有以下型号:

class Hospital(models.Model):
    name = models.CharField(max_length=200)
    authorized_users = models.ManyToManyField(User)

在医院管理页面上显示一个 filter_horizo​​ntal 小部件来管理 ManyToManyField 非常简单:

class HospitalAdmin(admin.ModelAdmin):
    filter_horizontal = ('authorized_users', )

admin.site.register(models.Hospital, HospitalAdmin)

但是,我真正想要的是在“更改用户”管理页面上显示该小部件,与用户的其余信息内联。理所当然地,ManyToManyFields 应该可以从两个方向修改 - 为单个医院授权多个用户,上述事实情况很好。但是,要授权多个医院的一个用户,目前的情况需要访问每个医院的管理页面并选择一个有问题的用户 - 荒谬。

我将补充一点,我正在使用 UserProfile 方法来存储有关用户的其他信息(他们是什么类型的用户等)。一种可能的解决方案是让医院的 ManyToManyField 引用 UserProfile 而不是 User。然后我可以将ManyToManyField(Hospital, through=Hospital.authorized_users.through) 添加到UserProfile,从而允许我将filter_horizo​​ntal 小部件添加到两端。但是,这是不理想的,因为稍后引用该连接会很痛苦。想象一下,我想获得给定医院的第一个用户授权。而不是hosp_name.authorized_users.all()[0],我必须做类似hosp_name.authorized_users.all()[0].user的事情。我什至不确定如何完成与 hosp_name.authorized_users.all() 等效的操作以获取完整列表(因为这将返回 UserProfiles 的列表,而不是 Users。

【问题讨论】:

    标签: django many-to-many


    【解决方案1】:

    更雄辩地说,我的目标是使多对多医院-用户关系的管理成为双向的。也就是说,在 Hospitals 的管理页面上,您将获得用户的 filter_horizo​​ntal,而在用户管理页面上,您将获得 Hospitals 的 filter_horizo​​ntal。

    我放弃了与 User 建立关系的想法,而是使用 UserProfile 建立关系。我最终使用了this 7 year old standing Django ticket 底部提到的确切代码。

    最后,我的代码是

    #models.py
    class ReverseManyToManyField(models.ManyToManyField):
        pass
    try:
        import south
    except ImportError:
        pass
    else:
        from south.modelsinspector import add_ignored_fields
        add_ignored_fields([".*\.ReverseManyToManyField$",])
    
    class Hospital(models.Model):
        name = models.CharField(max_length=200)
        authorized_users = models.ManyToManyField('UserProfile', blank=True)
        def __unicode__(self):
            return self.name
    
    class UserProfile(models.Model):
        user = models.OneToOneField(User)
        authorized_hospitals = ReverseManyToManyField(Hospital, through=Hospital.authorized_rads.through)
    
        def __unicode__(self):
            return self.user.username
    

    #admin.py
    ##### Stuff to register UserProfile fields in the admin site
    class UserProfileInline(admin.StackedInline):
        model=models.UserProfile
        can_delete = False
        verbose_name_plural = 'profiles'
        filter_horizontal = ('authorized_hospitals',)
    
    class UserAdmin(UserAdmin):
        inlines = (UserProfileInline, )
    
    class HospitalAdmin(admin.ModelAdmin):
        filter_horizontal = ('authorized_users', )
    
    admin.site.unregister(User)
    admin.site.register(User, UserAdmin)
    ##### END UserProfile Stuff
    
    admin.site.register(models.Hospital, HospitalAdmin)
    

    【讨论】:

    • 这对您在 Filter_horizo​​ntal 上建立反向关系有用吗? @alex-whittemore
    • 已经有一段时间了,但我记得,它确实完成了从两端编辑成员关系的目标。
    • 唯一的问题是我不使用南。所以不知道如何在不使用 south 的情况下修改代码。
    • 你试过了吗?据我记得,南方只在迁移过程中发挥作用。我认为,从外观上看,我上面的代码甚至被设计为在不使用它的情况下模块化地忽略 south。
    猜你喜欢
    • 2013-08-12
    • 2014-05-23
    • 2011-02-15
    • 2011-07-17
    • 2019-08-15
    • 2015-01-11
    • 2015-09-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多