Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Admin ManyToManyField

I've made a model (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') 

then I try to add inline block to allow assign opetest on 'change user' page (admin.py):

class ProfileAdmin(UserAdmin):     filter_horizontal = ('opetests',)  admin.site.unregister(User) admin.site.register(User, ProfileAdmin) 

And I got an error:

'ProfileAdmin.filter_horizontal' refers to field 'opetests' that is missing from model 'User'. 

I want to show opetests like Groups on change user page. How can I achieve that?

like image 421
baobee Avatar asked Nov 07 '11 22:11

baobee


People also ask

How do I show many to many fields in Django admin?

ManyToManyField fields aren't supported, because that would entail executing a separate SQL statement for each row in the table. If you want to do this nonetheless, give your model a custom method, and add that method's name to list_display. (See below for more on custom methods in list_display.)

How do I access my Django admin page?

To login to the site, open the /admin URL (e.g. http://127.0.0.1:8000/admin ) and enter your new superuser userid and password credentials (you'll be redirected to the login page, and then back to the /admin URL after you've entered your details).

Where is Django admin template?

To view the default admin template you can access it in the django/contrib/admin/templates/admin folder.

How do I change the administrator name in Django?

To change the admin site header text, login page, and the HTML title tag of our bookstore's instead, add the following code in urls.py . The site_header changes the Django administration text which appears on the login page and the admin site. The site_title changes the text added to the <title> of every admin page.


1 Answers

Hmm, I don't think you want inlines here.

You want to be using the Django admin's filter_horizontal:

https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.filter_horizontal

class ProfileAdmin(UserAdmin)     filter_horizontal = ('opetest',) 

That will give you the widget that you're describing, used to add/remove Groups on the User Change page.


Ok, based on your edits, updated answer - basically, what we have is a UserProfile, linked to each user.

The UserProfile contains a m2m relationship to opetest - which we show in the admin with a filter_horizontal. End result is something like this:

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) 

Let me know if you have any questions, or need anything further.

like image 56
victorhooi Avatar answered Sep 24 '22 06:09

victorhooi