Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save Grokzen/a64321dd69339c42a184 to your computer and use it in GitHub Desktop.

Select an option

Save Grokzen/a64321dd69339c42a184 to your computer and use it in GitHub Desktop.

Revisions

  1. Grokzen revised this gist Nov 2, 2022. 1 changed file with 6 additions and 0 deletions.
    6 changes: 6 additions & 0 deletions Symmetrical ManyToMany Filter Horizontal in Django Admin.py
    Original file line number Diff line number Diff line change
    @@ -5,6 +5,12 @@
    When adding a many-to-many (m2m) relationship in Django, you can use a nice filter-style multiple select widget to manage entries. However, Django only lets you edit the m2m relationship this way on the forward model. The only built-in method in Django to edit the reverse relationship in the admin is through an InlineModelAdmin.

    Below is an example of how to create a filtered multiple select for the reverse relationship, so that editing entries is as easy as in the forward direction.

    IMPORTANT: I have no idea for what exact versions of Django this will work for, is compatible with or was intended for.

    I am sure this have stopped working slightly for new:er versions of Django. I do not use this myself currently with any new code so i can't really tell for sure.

    !! Use code at your own risk !!
    """

    ### pizza/models.py ###
  2. Grokzen renamed this gist Dec 7, 2021. 1 changed file with 0 additions and 0 deletions.
  3. Grokzen renamed this gist Dec 7, 2021. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  4. Grokzen renamed this gist Aug 13, 2015. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  5. Grokzen revised this gist Aug 13, 2015. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,6 @@
    # Based on post from: https://snipt.net/chrisdpratt/symmetrical-manytomany-filter-horizontal-in-django-admin/#L-26
    # Only reposting to avoid loosing it.

    """
    When adding a many-to-many (m2m) relationship in Django, you can use a nice filter-style multiple select widget to manage entries. However, Django only lets you edit the m2m relationship this way on the forward model. The only built-in method in Django to edit the reverse relationship in the admin is through an InlineModelAdmin.

  6. Grokzen created this gist Aug 13, 2015.
    65 changes: 65 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,65 @@
    """
    When adding a many-to-many (m2m) relationship in Django, you can use a nice filter-style multiple select widget to manage entries. However, Django only lets you edit the m2m relationship this way on the forward model. The only built-in method in Django to edit the reverse relationship in the admin is through an InlineModelAdmin.

    Below is an example of how to create a filtered multiple select for the reverse relationship, so that editing entries is as easy as in the forward direction.
    """

    ### pizza/models.py ###

    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)