[英]Admin: Show related inline ManyToMany objects as MultipleChoiceField
我已经覆盖了 UserAdmin class 并希望将用户配置文件和一些相关对象添加为内联对象。
Userprofile 按预期工作,但对于 ManyToMany 关系,我现在得到一个包含相关对象的表。 这对我的应用程序来说并不是很理想,更改相关对象有点麻烦,并且不需要这种方式添加新对象。
我想要一个包含相关对象的简单 MultipleChoiceField 。 有没有简单的方法来实现这一目标?
这是我的用户配置文件/admin.py:
from django.contrib import admin
from django.contrib.auth import get_user_model
from django.contrib.auth.admin import UserAdmin
from django.utils.translation import gettext_lazy as _
from django_admin_listfilter_dropdown.filters import RelatedOnlyDropdownFilter
from driverslog.models import Branch
from driverslog.models import Car
from .models import Userprofile
User = get_user_model()
class ProfileInline(admin.TabularInline):
model = Userprofile
can_delete = False
max_num = 0
extra = 0
fk_name = 'user'
class CarInline(admin.TabularInline):
model = Car.users.through
can_delete = True
verbose_name = _('Car')
verbose_name_plural = _('Cars')
extra = 0
class BranchInline(admin.TabularInline):
model = Branch.users.through
can_delete = True
verbose_name = _('Branch')
verbose_name_plural = _('Branches')
extra = 0
class CustomUserAdmin(UserAdmin):
inlines = (ProfileInline, BranchInline, CarInline)
list_display = ('username', 'first_name', 'last_name', 'is_staff', 'is_superuser', 'represents')
list_filter = ('is_active', 'is_staff', 'is_superuser', ('groups', RelatedOnlyDropdownFilter),
('branches', RelatedOnlyDropdownFilter), ('profile__represent', RelatedOnlyDropdownFilter),
('car', RelatedOnlyDropdownFilter))
def represents(self, obj):
return obj.profile.represent.count()
represents.short_description = _('Represents')
admin.site.unregister(User)
admin.site.register(User, CustomUserAdmin)
我现在在不使用内联字段的情况下解决了它。
我所做的是覆盖 UserChangeForm 并添加反向关系的字段。 它按预期工作,到目前为止我没有发现任何缺点(直到现在......)。
管理员.py:
class CustomUserAdmin(UserAdmin):
inlines = (ProfileInline,)
form = UserForm
...
fieldsets = (
(_('Personal info'), {'fields': ('username', 'first_name', 'last_name', 'email')}),
(_('Permissions'), {'fields': ('is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions')}),
(_('Assignments'), {'fields': ('branches', 'cars')}),
)
forms.py:
class UserForm(UserChangeForm):
branches = forms.ModelMultipleChoiceField(queryset=Branch.objects.all())
cars = forms.ModelMultipleChoiceField(queryset=Car.objects.all())
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
instance = kwargs.get('instance')
if instance:
self.fields["branches"].initial = instance.branches.all().values_list('id', flat=True)
self.fields["cars"].initial = instance.cars.all().values_list('id', flat=True)
def save(self, commit=True):
if self.is_valid():
self.instance.cars.set(self.cleaned_data.get('cars'))
self.instance.branches.set(self.cleaned_data.get('branches'))
return super().save(commit)
模型.py:
class Userprofile(models.Model):
class Meta:
verbose_name = _('Profile')
verbose_name_plural = _('Profiles')
user = models.OneToOneField(get_user_model(), on_delete=models.CASCADE, unique=True, related_name='profile', verbose_name=_('User'))
represent = models.ManyToManyField(get_user_model(), related_name='represent', blank=True, verbose_name=_('Represents'))
2017年后,django增加了filter_horizo ntal属性。
class CustomUserAdmin(UserAdmin):
filter_horizontal = ('branches', 'cars')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.