Представьте ManyToMany в Admin Django как горизонтальный фильтр с использованием related_name - PullRequest
0 голосов
/ 13 сентября 2018

У меня есть следующее:

class User(models.Model)
    blablabla

class Product(models.Model)
    authorized_users = models.ManyToManyField(
        User,
        related_name='shared_products',
    )

Я уже настроил администратора Product для отображения authorized_users в качестве горизонтального фильтра, чтобы выбрать всех пользователей, которые могут редактировать продукт.

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

admin.site.register(Product, ProductAdmin)

Проблема в том, что я хочу сделать то же самое в администраторе User, что означает, что я хочу иметь горизонтальный фильтр для shared_products, чтобы выбрать продукты, которые этот пользовательумеет редактировать.Я пробовал следующее, которое явно не работает:

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

admin.site.register(User, UserAdmin)

Другие ответы, которые я нашел, рекомендуют использовать Inlines, но, как я видел, они используются для редактирования экземпляра модели на другом конце, чтоне я ли то, что я хочу сделать.

У кого-нибудь есть идеи, как этого добиться?

1 Ответ

0 голосов
/ 13 сентября 2018
class UserAdminForm(forms.ModelForm):
  products = forms.ModelMultipleChoiceField(
    queryset=Product.objects.all(), 
    required=False,
    widget=FilteredSelectMultiple(
      verbose_name=_('Products'),
      is_stacked=False
    )
  )

  class Meta:
    model = User

  def __init__(self, *args, **kwargs):
    super(UserAdminForm, self).__init__(*args, **kwargs)

    if self.instance and self.instance.pk:
      self.fields['products'].initial = self.instance.products.all()

  def save(self, commit=True):
    user = super(UserAdminForm, self).save(commit=False)

    if commit:
      user.save()

    if user.pk:
      user.products = self.cleaned_data['products']
      self.save_m2m()

    return user

class UserAdmin(admin.ModelAdmin):
  form = UserAdminForm
...