Django admin with many to many choices

Viewed 2939

I have the following models.py and admin.py files. The intention is to allow for selection of multiple categories for a given product if necessary.

models.py

class Product(models.Model):
    organization = models.ForeignKey(Organization)
    name = models.CharField(max_length=50)
    brief = models.CharField(max_length=100)
    descrip = models.TextField(max_length=1300)
    categories = models.ManyToManyField('Product_Category')

class Product_Category(models.Model):
    cats = {"AUT":"Automation", "PWA":"Personal Wealth Advisory", 
            "BCH":"Blockchain", "LOS":"Loan Origination", "FX":"Foreign Exchange"}
    choices = tuple((human, c) for human, c in cats.items())
    name = models.CharField(max_length=32, choices=choices)

admin.py

 from .models import Product, Product_Feature, Organization, Product_Category

class PFeatureInLine(admin.StackedInline):
    model = Product_Feature
    extra = 1

class ProductForm(forms.ModelForm):
    logo_file = forms.ImageField()

    def save(self, commit=True):
        logo_file = self.cleaned_data.get("logo_file", None)
        self.instance.logo = b64encode(logo_file.read()).decode("utf-8")
        return forms.BaseModelForm.save(self, commit=commit)

    class Meta():
        exclude = ["logo"]
        model = Product

class ProductAdmin(admin.ModelAdmin):
    form = ProductForm
    inlines = [PFeatureInLine,]

admin.site.register(Product, ProductAdmin)
admin.site.register(Organization)

This results in the following, when accessing a Products object through admin:

enter image description here

2 Answers

The real answer is buried in the comments under the accepted answer.

For Many2Many the available items are not primarily defined by choices but by the records in the joined table. In your case, the product_category table needs to be populated with those 5 choices.

It's a little frustrating that makemigrations can't handle this for you but oh well.

Related