djangomodelmultiplechoicefield

Django ModelMultipleChoiceField problem to save data in DB


I used to have a Multi select box in my form filled with a JSON list

forms.py

FRUIT_CHOICES= [
    ('Oranges', 'Oranges'),
    ('Cantaloupes', 'Cantaloupes'),
    ('Mangoes', 'Mangoes'),
    ('Honeydews', 'Honeydews')
    ]

class AddRecordForm(forms.ModelForm):
    testrever = forms.MultipleChoiceField(choices=FRUIT_CHOICES)

And so I used a JSON field in my models.py like this

models.py

class Record(models.Model):
    testrever = models.JSONField(max_length=500)

It worked like a charm and I was able to save the selection and load it back when the form was recalled.

But now in forms.py I need to modify the forms.MultipleChoiceField to forms.ModelMultipleChoiceField which is populated by a queryset like this

class AddRecordForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        self.storage_pk = kwargs.pop('pk')
        super(AddRecordForm, self).__init__(*args, **kwargs)
        self.fields['testrever'].queryset = BDC.objects.filter(ref=self.storage_pk).values_list('model', flat=True) 


    testrever = forms.ModelMultipleChoiceField(widget=forms.widgets.SelectMultiple, queryset=None)

class Meta:
    model = Record
    exclude = ("user",)
    fields = ['id','first_name','last_name','email', 'phone' ,'address', 'city' ,'state' ,'zipcode' ,'regarde' ,'testrever']

So now my models.JSONField in models.py is no longer working since I'm not rendering a JSON list format anymore.

What kind of field should I use in models.py to make it work again?


Solution

  • If you pick zero, one or multiple items of another model, you use a ManyToManyField [Djangp-doc]:

    class Fruit(models.Model):
        name = models.CharField(max_length=128, unique=True)
    
        def __str__(self):
            return name
    
    
    class Record(models.Model):
        testrever = models.ManyToManyField(Fruit, blank=True)

    This also uses a ModelMultipleChoice field as default form field. So you only have to plug in a different widget:

    class RecordForm(forms.ModelForm):
        class Meta:
            model = Record
            fields = '__all__'
            widgets = {'testrever': forms.SelectMultiple}

    while most databases offer a JSON field nowadays, which is useful for unstructered data, for structured data, using a JSONField is not a good idea as it violates first normal form [wiki].