Django: Show filter_horizontal on user admin page

I have the following model:

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

      

Displaying the filter_horizontal filter on the hospital admin page to manage a ManyToManyField is pretty simple:

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

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

      

However, what I would REALLY want to show is that the AS WELL widget on the admin page "Change User" is embedded in the rest of the user info. Of course, ManyToManyFields MUST be modifiable from both directions - to authorize multiple users for one hospital, the above situation is fine. However, to authorize a single user across multiple hospitals, the current situation would require visiting the admin page for each hospital and selecting one user in question, which is absurd.

I'll add that I'm using the UserProfile methodology to store additional information about users (what type of user they are, etc.). One POSSIBLE solution is to make the sick ManyToManyField a UserProfile reference instead of User. Then I could add ManyToManyField(Hospital, through=Hospital.authorized_users.through)

in UserProfile

, which will allow me to add filters filter_horizontal to both ends. However, this is not ideal as pain will later refer to the connection. Imagine that I want to get the first user authorized for this hospital. Instead, hosp_name.authorized_users.all()[0]

I would need to do something like hosp_name.authorized_users.all()[0].user

. I'm not even sure how I would implement the equivalent hosp_name.authorized_users.all()

to get the full list (since that would return a list UserProfiles

, not User

s.

+3


source to share


1 answer


More eloquently it is stated that my goal was to turn the management of the relationship between patients and many patients in a bidirectional manner. For example, on the administration page for hospitals, you will get a horizontal filter for users, and on the user administration page, you will get a horizontal filter for hospitals.

I gave up the idea of ​​creating a user relationship and did it with UserProfile instead. I ended up using the exact code mentioned at the bottom of this 7 year old Django permanent ticket .

at the end my code



#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

      

and

#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)

      

+6


source







All Articles