带有ID的Ajax问题的Django依赖下拉列表

时间:2018-07-24 08:55:21

标签: ajax django dropdown id

我正在尝试实现一个依赖下拉列表。 Vitor Freitas在他的博客中做了这个,我基本上是在关注他的solution。 (一个非常酷的博客,提供了清晰的代码,这对我很有帮助。)

我在页面上采用了它,但是它恰好卡在应该限制下拉列表的位置。

我很确定我弄混了外键或Ajax / javascript(因为我不了解ajax + javascript。)

也许您看到了我的“基本”错误,可以为我提供帮助。会很感激的。

models.py

class Country(models.Model):
    name = models.CharField(max_length=3)
    def __str__(self):
        return self.name

class Provider(models.Model):
    country = models.ForeignKey(Country, on_delete=models.CASCADE)
    name = models.CharField(max_length=30)

    def __str__(self):
        return self.name

class CustomerSubsidiary(models.Model):
    subCountry = models.ForeignKey(Country, on_delete=models.SET_NULL, null=True)
    subName = models.CharField(max_length=50, blank=True)

urls.py

urlpatterns = [
    path('test', views.CustomerSubsidiaryListView.as_view(), name='CustomerSubsidiary_changelist'),
    path('test/add/', views.CustomerSubsidiaryCreateView.as_view(), name='CustomerSubsidiary_add'),
    path('test/<int:pk>/', views.CustomerSubsidiaryUpdateView.as_view(), name='CustomerSubsidiary_change'),
    path('ajax/load-provider/', views.load_provider, name='ajax_load_provider'),
]

views.py

def load_provider(request):
    country_id = request.GET.get('country')
    provider = Provider.objects.filter(country_id=country_id).order_by('name')
    return render(request, 'Customer/city_dropdown_list_options.html', {'provider': provider})

providerForm

class ProviderForm(forms.ModelForm):
    class Meta:
        model = CustomerSubsidiary
        fields = ('subName', 'subCountry', 'provider')

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

customersubsidiary_form.html

{% extends 'base.html' %}

{% block content %}

  <h2>Provider Form</h2>

  <form method="post" id="providerForm" data-provider-url="{% url 'ajax_load_provider' %}" novalidate>
    {% csrf_token %}
    <table>
      {{ form.as_table }}
    </table>
    <button type="submit">Save</button>
    <a href="{% url 'CustomerSubsidiary_changelist' %}">Nevermind</a>
  </form>




  <script>
    $("#id_country").change(function () {
      var url = $("#providerForm").attr("data-provider-url");  
      var countryId = $(this).val();  

      $.ajax({                       
        url: url,                    
        data: {
          'country': countryId       
        },
        success: function (data) { 
          $("#id_provider").html(data);  
        }
      });

    });
  </script>

{% endblock %}

jquery已加载到base.html中。

city_dropdown_list_options.html

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

2 个答案:

答案 0 :(得分:0)

我在页面的源代码中看到ID的名称错误,这意味着它们与views.py不匹配。

views.py 中应该是:

def load_provider(request):
    country_id = request.GET.get('subCountry') #<-- change country to subCountry, that means the attribute name of the original class

ajax脚本中,将ID更改为#id_subCountry,将国家/地区更改为subCountry:

<script>
    $("#id_subCountry").change(function () {
      var url = $("#providerForm").attr("data-provider-url");  // get the url of the `load_cities` view
      var subCountryId = $(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: {
          'subCountry': subCountryId       // add the country id to the GET parameters
        },
        success: function (data) {   // `data` is the return of the `load_cities` view function
          $("#id_provider").html(data);  // replace the contents of the city input with the data that came from the server
        }
      });

    });
  </script>

答案 1 :(得分:0)

此处的问题:self.fields ['provider']。queryset = Provider.objects。无()。当您在表单字段“ provider”中从“ request.POST”添加数据时,将始终为“ none”。尝试从代码中删除此行或添加它:

views.py/edit

if request.method == "POST":
        ProviderForm.request_change=True

        form = ProviderForm(request.POST)

forms.py

class ProviderForm(forms.ModelForm):
request_change=False

class Meta:
    model = CustomerSubsidiary
    fields = ('subName', 'subCountry', 'provider')

def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    if request_change:
        request_change=False
    else:
        self.fields['provider'].queryset = Provider.objects.none()