I have a model in which one of its fields is a postgres.fields.JSONField.
The Json that is going to be stored there is a variable dictionary of IDs referencing other items (possible relations/attributes) in the database.
Allow me to be more specific:
Basically, I'm trying to create a discount system, in which some discounts would apply to certain products. The JSON field contains the constraints to know what products can receive a discount.
For instance:
If I want to apply a 50% off to all products that fall under the "Beverages" category, and the "Beverages" category has id
5in the database, the discount record would look like:discount_type='percent' discount='0.5' filter_by={ 'category': [5] }If I wanted to apply a $20 off to all the products in the "Beverages" category AND that are manufactured by, let's say, CocaCola, the
filter_bydictionary would look like:discount_type='fixed amount' discount='20' filter_by={ 'category': [5], 'manufacturer': [2] # Assuming coca-cola is the Manufacturer # with id==2 in the 'Manufacturers' # table of the database (NOTE: this is # needed since CocaCola manufactures # products besides "Beverages") }If I wanted to apply a 25% off to a particular product (let's say to the product whose
idis3) the dictionary would look like:discount_type='percent' discount='0.25' filter_by={ 'id': [3] }
This idea seems to be flexible enough for my needs, and I'm happy (so far) with it.
Now, the problem comes on how to enter these values in the Django admin area for the Discount model.
As expected, the filter_by dictionary renders as as a text field that initially looks like this:
If I want to add fields to it, I need to write the exact JSON of what I want... Which means that if I want to apply a discount to the "Beverages" category, I need to go figure out which ID that category has in the database, and then manually type {"category": [5]}, while being extremely careful when typing the ', the :, make sure that I don't miss a ] or a [...
Thaaaat... well, that is not very helpful...
Since I am only going to be filtering by a few fields (category, manufacturer, product...) which are actually lists of IDs of other elements of the database, I would like to show a big MultiSelect box per thingy I can filter for, so I can see a user friendly list of all the elements I can filter by, select a few, and then, when I click on "Create discount", I would get the filter_by dictionary (I'm still far from worrying about how to generate the dictionary, since I don't even know how to properly render the Admin form).
Something like what Django Admin automatically did for my Products' categories:
That is really, really, nice: One product can belong to several categories. For that, Django renders, side by side, two <select multiple boxes, with the available categories, and the categories that the product already belongs to... I can add/remove categories through the stroke of a mouse... Really, really nice. But Django can do that because it knows that the categories are a ManyToMany relation in the Product model.
class Product(models.Model):
parent = models.ForeignKey('self', null=True, blank=True)
manufacturer = models.ForeignKey('Manufacturer')
categories = models.ManyToManyField('Category',
related_name='products', blank=True)
The problem with the Discount model is that there is no ManyToMany field to category, manufacturer or product. Poor Django doesn't know that a Discount is related to all those things: It only knows there's a Json field.
I would really like to be able to show a bunch of those <select> in the Django Area listing all the possible filters (Category, Manufacturer, ID...) that can be stored in the filter_by dictionary (one entry with the double <select> for Category showing all the available categories in the database, one entry for Manufacturer, showing all the available manufacturers... etcetera). But I really, really don't know how to do that.
I could bore you with a bunch of tries I've done, using Widgets, trying to represent the JSON field through a form, through forms.ModelMultipleChoiceField (which by the way, seems to have been the closest thing to what I want, although still very far)... But I think that is kind of pointless, since nothing came close to what I wanted.
As usual, thank you for reading this huge email and thank you in advance. Any hint will be really appreciated, even just a you should take a look to "this"


