Django Admin ManyToManyField

#django #django-models #django-admin #manytomanyfield #django-orm

#django #django-модели #django-администратор #manytomanyfield #django-orm

Вопрос:

Я создал модель (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')
  

затем я пытаюсь добавить встроенный блок, чтобы разрешить назначение opetest на странице «изменить пользователя» (admin.py ):

 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'.
  

Я хочу показать opetests как группы на странице изменения пользователя. Как я могу этого добиться?

Комментарии:

1. Если приведенный ниже ответ ответил на ваш вопрос, не могли бы вы отметить его? Если этого не произошло, пожалуйста, дайте нам знать, что еще вам нужно, и мы можем попытаться помочь.

Ответ №1:

Хм, я не думаю, что вам нужны встроенные строки здесь.

Вы хотите использовать filter_horizontal администратора Django:

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

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

Это даст вам виджет, который вы описываете, используемый для добавления / удаления групп на странице смены пользователя.


Хорошо, основываясь на ваших правках, обновленный ответ — по сути, у нас есть пользовательский профиль, связанный с каждым пользователем.

Пользовательский профиль содержит отношение m2m к opetest, которое мы показываем в admin с помощью filter_horizontal. Конечный результат выглядит примерно так:

Opetest с фильтром по горизонтали

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)
  

Дайте мне знать, если у вас возникнут какие-либо вопросы или вам понадобится что-нибудь еще.

Комментарии:

1. параметры filter_horizontal должны относиться к полям модели. Но opetest здесь является моделью.

2. Хм, почему бы вам не создать opetest поле в UserProfile и не сопоставить его с opetest ? Это поле m2m, поэтому на самом деле не должно иметь значения, на каком конце связи оно находится — тогда вы можете просто использовать filter_horizontal в opetest поле?

3. Извините, Виктор, не могли бы вы, пожалуйста, описать, как я могу создать поле в UserProfile и сопоставить его с opetest?

4. Итак, я добавил поле, но оно не работает: ‘class ProfileAdmin(UserAdmin):’ ‘usertests = models. ManyToManyField(opetest, blank= True)’ ‘ProfileAdmin.filter_horizontal’ ссылается на поле ‘usertests’, которое отсутствует в модели ‘User’.’ filter_horizontal = (‘usertests’,)

5. Хм, не могли бы вы отредактировать свой вопрос и вставить свой полный models.py и admin.py , пожалуйста? Я немного смущен предыдущим текстом, который у вас есть class ProfileADmin(UserAdmin) , который выглядит как admin.py , но затем в следующей строке вы определяете поле модели. Если вы вставите свой полный код, мы сможем помочь вам упростить его работу.