Wazy
Wazy

Reputation: 494

Django dependent drop down not functioning properly

Django noob

I am currently attempting to implement a dependent drop down list for car models - manufactures I am following this tutorial

I have the form displaying properly but the issue I am facing is if I select a manufacture no models are displayed.

I have spent a bunch of time attempting to solve this and I am out of ideas

All feedback welcome!

forms.py

from blog.models import Post, Manufactures, Models

class PostForm(ModelForm):
    class Meta:
        model = Post
        fields = 'title', 'manufacture', 'model', 'content', 'image', 'aspiration'

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['model'].queryset = Models.objects.none() 

  

models.py

    class Manufactures(models.Model):
    manufacture_id = models.AutoField(primary_key=True)
    manufacture = models.CharField(max_length=55)
        
    def __str__(self):
        return self.manufacture

    def get_absolute_url(self):
        return reverse('db-manufactures', kwargs={'pk': self.pk})


class Models(models.Model):
    model_id = models.AutoField(primary_key=True)
    model = models.CharField(max_length=55)
    model_manufacture = models.ForeignKey(Manufactures, on_delete=models.CASCADE)
    
    def __str__(self):
        return self.model

    def get_absolute_url(self):
        return reverse('blog-models', kwargs={'pk': self.pk})

Views.py

    def loadModels(request):
    manufacture_id = request.GET.get('model_manufacture')
    models = Models.objects.filter(manufacture_id = manufacture_id)
    return render(request, 'model_dropdown_list.html', {'models': models})

class PostCreateView(LoginRequiredMixin, CreateView):
    model = Post
    form_class = PostForm

    def form_valid(self, form):
        form.instance.author = self.request.user
        return super().form_valid(form)
    
    def save(self, *args, **kwargs):
        super(Post,self).save(*args, **kwargs)

model_dropdown_list.html

    <option value="">---------</option>
    {% for model in models %}
    <option value="{{ model.pk }}">{{ model.name }}</option>
    {% endfor %}

post_form.html

    {% extends "blog/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="content-section">
    <form method="post" id="modelForm" data-models-url="{% url 'ajax' %}" novalidate>
        {% csrf_token %}
        <fieldset class="form-group">
            <legend class="border-bottom mb-4">Create Post</legend>
            {{ form|crispy }}
        </fieldset>
        <div class="form-group">
            <button class="btn btn-outline-info" type="submit">Post</button>
        </div>
    </form>
</div>

<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script>
    $("#id_manufacture").change(function () {
        var url = $("#PostForm").attr("data-models-url");  // get the url of the `load_cities` view
        var manufactureId = $(this).val();  // get the selected country ID from the HTML input

        $.ajax({                       // initialize an AJAX request
            url: url,                    // set the url of the request (= localhost:8000/hr/ajax/load-cities/)
            data: {
                'manufacture': manufactureID       // add the country id to the GET parameters
            },
            success: function (data) {   // `data` is the return of the `load_cities` view function
                $("#id_model").html(data);  // replace the contents of the city input with the data that came from the server
            }
        });

    });
</script>
{% endblock content %}

urls.py

    urlpatterns = [
    path('post/new/', PostCreateView.as_view(), name='post-create'),
    path('ajax/load-models', views.loadModels, name='ajax')
]

Update

The error was in my post_form.html I had use a lowercase d and not an uppercase

<script>
$("#id_manufacture").change(function () {
    var url = $("#PostForm").attr("data-models-url");  
    var manufactureId = $(this).val(); !!!lowercase "d" on manufactureId

    $.ajax({                      
        url: url,                    
        data: {
            'manufacture_id': manufactureID !!!uppercase "D"       
        },
        success: function (data) {   
            $("#id_model").html(data);  
        }
    });

});

New Issue

enter image description here

It seems to be making the correct call and is grabbing the proper id except it is behaving strangely. When I select a manufacture it runs the request once. If I then change my mind and select a different manufacture it runs the call twice(with the correct id) and so on.

except when on the page after you select a manufacture the model drop down is empty

enter image description here

Solution

def loadModels(request):
model_manufacture_id = request.GET.get('model_manufacture')
models = Models.objects.filter(model_manufacture_id=model_manufacture_id) #orderby?
return render(request, 'blog/model_dropdown_list.html', {'models': models})

Upvotes: 0

Views: 196

Answers (1)

FabianClemenz
FabianClemenz

Reputation: 348

This looks like in the Tutorial, but i can't say 100% because your urls.py is missing. Did you check developer console? Try to console.log(manufactureId) and console.log(url) to check if you have the right data needed

also what i can see -> your model dont have a property called name, it is called model In your Models class - so you need to get model.model Instead of model.name in model_dropdown_list.html

class Models(models.Model):
    model_id = models.AutoField(primary_key=True)
  --> model = models.CharField(max_length=55)
    model_manufacture = models.ForeignKey(Manufactures, on_delete=models.CASCADE)
    
    def __str__(self):
        return self.model

    def get_absolute_url(self):
        return reverse('blog-models', kwargs={'pk': self.pk})

The template has to look like this:

    <option value="">---------</option>
    {% for model in models %}
    <option value="{{ model.pk }}">{{ model.model }}</option>
    {% endfor %}

PS: what i can See, you want to access your form with $("#PostForm") but it’s Id is modelForm - please check your namings :)

Upvotes: 1

Related Questions