Adding a ManyToManyWidget to the reverse of a ManyToManyField in the Django Admin

前端 未结 5 1036
我寻月下人不归
我寻月下人不归 2020-12-13 07:08

Let\'s say I have a simple blog app in Django 1.4:

class Post(models.Model):
    title = …
    published_on = …
    tags = models.ManyToManyField(\'Tag\')

c         


        
5条回答
  •  执念已碎
    2020-12-13 07:26

    You can add a symmetrical many to many filter this way.

    Credit goes to https://gist.github.com/Grokzen/a64321dd69339c42a184

    from django.db import models
    
    class Pizza(models.Model):
      name = models.CharField(max_length=50)
      toppings = models.ManyToManyField(Topping, related_name='pizzas')
    
    class Topping(models.Model):
      name = models.CharField(max_length=50)
    
    ### pizza/admin.py ###
    
    from django import forms
    from django.contrib import admin
    from django.utils.translation import ugettext_lazy as _
    from django.contrib.admin.widgets import FilteredSelectMultiple
    
    from .models import Pizza, Topping
    
    class PizzaAdmin(admin.ModelAdmin):
      filter_horizonal = ('toppings',)
    
    class ToppingAdminForm(forms.ModelForm):
      pizzas = forms.ModelMultipleChoiceField(
        queryset=Pizza.objects.all(), 
        required=False,
        widget=FilteredSelectMultiple(
          verbose_name=_('Pizzas'),
          is_stacked=False
        )
      )
    
      class Meta:
        model = Topping
    
      def __init__(self, *args, **kwargs):
        super(ToppingAdminForm, self).__init__(*args, **kwargs)
    
        if self.instance and self.instance.pk:
          self.fields['pizzas'].initial = self.instance.pizzas.all()
    
      def save(self, commit=True):
        topping = super(ToppingAdminForm, self).save(commit=False)
    
        if commit:
          topping.save()
    
        if topping.pk:
          topping.pizzas = self.cleaned_data['pizzas']
          self.save_m2m()
    
        return topping
    
    class ToppingAdmin(admin.ModelAdmin):
      form = ToppingAdminForm
    
    admin.site.register(Pizza, PizzaAdmin)
    admin.site.register(Topping, ToppingAdmin)
    

提交回复
热议问题