0

I got a Category model

class Category(models.Model):
    name = models.CharField(max_length=120,default='', verbose_name=_('name'))
    color = ColorField(default='#FF0000')

and a Product model

class Product(models.Model):
     name = models.CharField(max_length=120)
     category = models.ForeignKey(Category, on_delete=models.CASCADE, default=None)
     ...

In the Product admin page, I want to make the category drop-down to show the name with the category's color. With help from this question: Django form field choices, adding an attribute

I manage to make a colored category field in my admin page: enter image description here

This is the code (added to product/admin.py):

class SelectWOA(Select):
    def create_option(self, name, value, label, selected, index, 
                      subindex=None, attrs=None):
        option_dict = super(SelectWOA, self).create_option(name, value, 
            label, selected, index, subindex=subindex, attrs=attrs)
            #Category.objects.
        try:
            option_dict['attrs']['style'] =  'color: ' +  Category.objects.get(name=label).color + ';' 
        except:
            pass
            
        return option_dict

from django.forms import ChoiceField, ModelChoiceField
from category.models import Category
class ProductAdminForm(ModelForm):
    test_field = ModelChoiceField(queryset=Category.objects.all(), widget=SelectWOA())
    class Meta:
        model = Product
        exclude = ['category']
        fields = ('name', 'image', 'image2', 'category', 'test_field',)





from django.db import models
class ProductCastumAdmin(admin.ModelAdmin):
    form = ProductAdminForm

but the test_field does not know I want it to "connect" to the category field and replace it. So when I save the form, the data I put inside test field is not saved as the category. My question is after I excluded the category field, how can I replace it with the test field so it could save the data as if it was the category field?

Jai
  • 819
  • 7
  • 17
Roni
  • 127
  • 1
  • 17
  • 1
    rename test_field to category, and drop test_field of Meta's fields, it will work as expected. – Blackdoor Jul 14 '20 at 04:36
  • @Blackdoor thank you! it was the solution to my problem. Now I want to show the same 'category' field in the `list_editable` in my `class ProductCastumAdmin(admin.ModelAdmin)` but it shows the default category and not the one build in the `ProductAdminForm` class, is there a way to connect them? – Roni Jul 14 '20 at 22:25
  • Did you register it to site? – Blackdoor Jul 14 '20 at 22:49
  • you mean `from django.contrib.sites.models import Site`? no, why would I want to do that? for what model and for what reason? – Roni Jul 14 '20 at 23:11
  • 1
    using formfield_overrides in ModelAdmin – Blackdoor Jul 14 '20 at 23:47

1 Answers1

0

So with a great help from @Blackdoor this is my solution: Thank you!

# select that change the color of the option based on the category of the product
class SelectWOA(Select):
    def create_option(self, name, value, label, selected, index, 
                      subindex=None, attrs=None):
        option_dict = super(SelectWOA, self).create_option(name, value, 
            label, selected, index, subindex=subindex, attrs=attrs)
            #Category.objects.
        try:
            option_dict['attrs']['style'] =  'color: ' +  Category.objects.get(name=label).color + ';' 
        except:
            pass
            
        return option_dict

from django.forms import ChoiceField, ModelChoiceField
from category.models import Category

class ProductAdminForm(ModelForm):
    category = ModelChoiceField(queryset=Category.objects.all(), widget=SelectWOA())
    class Meta:
        model = Product
        fields = ('name', 'image', 'image2', 'category',)


from django.db import models
class ProductCastumAdmin(admin.ModelAdmin):
    form = ProductAdminForm
    formfield_overrides = {
        models.ForeignKey: {'widget': SelectWOA},
    }
    fields = ( 'name', 'image', 'image2', 'category')
Roni
  • 127
  • 1
  • 17