pythondjangomodelmultiple-select

Django Models Multiple Field Saving


I'm trying to create an object in my Order model. My js return a list of multiple values for Model database however I can not save multiple values that I received from ajax as a list. I see it's an array in js and a list in django but it's not happening. I've tried ManyToManyField instead of ForeignKey for my Order model model field, but that did not work too.

Is there any way to save multiple values (list) that are already objects in my other models?

models.py

from django.db import models

class Car(models.Model):
    name = models.CharField(max_length=80)
    country = models.CharField(max_length=100)

    def __str__(self):
        return str(self.name)

class Model(models.Model):
    name = models.CharField(max_length=50)
    car = models.ForeignKey(Car, on_delete=models.CASCADE)

    def __str__(self):
        return f"{self.car}-{self.name}"

class Order(models.Model):
    car = models.ForeignKey(Car, on_delete=models.CASCADE)
    model = models.ForeignKey(Model, on_delete=models.CASCADE)

    def __str__(self):
        return str(self.pk)

views.py

def create_order(request):
    if request.method == 'POST': 
        print("***", request.POST)
        my_car_id = request.POST.get('car')         
        my_model_id = request.POST.getlist('model[]') 
        print("***", my_car_id, my_model_id)
        print("***", type(my_car_id), type(my_model_id))
        car_obj = models.Car.objects.get(id=my_car_id) 
        model_obj = models.Model.objects.get(id=my_model_id) 
        print("obj", car_obj, model_obj)
        models.Order.objects.create(car=car_obj, model=model_obj) 
        return JsonResponse({'created':True}) 
    return JsonResponse({'created':False})

html

<form id="car-form">
    {% csrf_token %}
    <div class="row">
        <div class="col">
            <label for="cars-data-box">Choose a car</label>
            <select style="width: 15rem;" class="form-control" id="cars-data-box">
                <option value="---">---</option>
            </select>
        </div>
        <div class="col">
            <label for="models-data-box">Choose a model</label>
            <select multiple style="width: 15rem;" class="form-control" id="models-data-box">
                <option value="---">---</option>
            </select>
        </div>
        <input type="hidden" name="car">
    </div>
    <div id="button-box" class="row pt-2">
        <div class="col">
            <button id="submit-form" type="submit" class="btn btn-secondary">Save</button>
        </div>
    </div>
</form>

js

console.log('main.js working')
var carBox = document.getElementById("cars-data-box")
var modelBox = document.getElementById("models-data-box")
var btn = document.getElementById("submit-form")
var csrf = document.getElementsByName('csrfmiddlewaretoken')
var carForm = document.getElementById('car-form')
var alertBox = document.getElementById('alert-box')

$.ajax({
    type: 'GET', 
    url: '/cars-json/', 
    success: function(response){ 
        var allCars = response.cars
        console.log("all cars:", allCars)
        for(var i=0; i< allCars.length; i++){
            var carObj = allCars[i];
            var carOpt = document.createElement('option');
            carOpt.value = carObj.id;
            carOpt.innerHTML = carObj.name;
            carBox.appendChild(carOpt);
        }        
    },
    error: function(error){ 
        console.log(error) 
    }
})

$(document).ready(function(){
    $(carBox).on('change', function(){ 
        var selectedCar = $(this).val(); 
        console.log("selectedCar", selectedCar);
        $(modelBox).empty(); 
        $.ajax({
            type:'GET',
            url:'/models-json/',
            success:function(response){
                var allModels = response.models
                console.log("allModels", allModels)
                possibleModels = allModels.filter( merhaba => merhaba.car_id == selectedCar ); 
                console.log("possibleModels", possibleModels);
                for(var i=0; i<possibleModels.length; i++){ 
                    var modelObj =  possibleModels[i]; 
                    var modelOpt = document.createElement('option'); 
                    modelOpt.value = modelObj.id; 
                    modelOpt.innerHTML =  modelObj.name; 
                    modelBox.appendChild(modelOpt); 
                }
            }
        })
    })
})

carForm.addEventListener('submit', e=>{ 
    e.preventDefault() 
    console.log('submitted', carBox.value, modelBox.value)
    // var selected_models = []
    // for(var i of document.getElementById('models-data-box').options){
    //     if(i.selected_models){
    //         selected_models.push(i.value)
    //     }
    // }
    var selected_models = $(modelBox).val()
    console.log("selected_models", selected_models)
    $.ajax({ 
        type:'POST',  
        url:'/create/',         
        data:{ 
            'csrfmiddlewaretoken':csrf[0].value, 
            'car':carBox.value, 
            'model':selected_models, 
        },
        success:function(response){ 
            console.log(response)
        },
        error:function(error){
            console.log(error)
        }
    })
})

Solution

  • You need bulk_create like this:

    def create_order(request):
       if request.method == 'POST':
          # rest of the code    
          model_objs = models.Model.objects.filter(id__in=my_model_id) 
          models.Order.objects.bulk_create(
             [models.Order(car=car_obj, model=model_obj) for model_obj in model_objs]
          )