Django Materialize Multiple Dropdowns
Это может быть довольно обширным - поэтому любая помощь будет высоко оценена.
Похожие:
- Материализация CSS (с django) выпадающая форма не работает
- Как реализовать трехсторонний зависимый/цепной выпадающий список с помощью Django?
Я работаю над проектом, включающим зависимые выпадающие меню, следуя этому учебнику по django.
Единственное отличие в том, что я работаю с materialize css/js. Проблема в том, что выпадающие окна не заполняются, а заполняются только после того, как я размещу форму - Pre-"post", и Post-"post". Когда я не инициирую materialize - форма работает . Materialize css/js все еще необходим, так как он поддерживает согласованность между другими страницами.
Даже после того, как я инициализировал 'select' после загрузки Materialize js: (Materialize docs here)
HTMLs
Base.html
<head>
{% load static %}
<!-- Prism CSS -->
<link href="{% static "tinymce/css/prism.css" %}" rel="stylesheet">
<!-- Compiled and minified JavaScript -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<script>
{% comment %} $(document).ready(function(){
$('select').formSelect();
}); {% endcomment %}
document.addEventListener('DOMContentLoaded', function() {
var elems = document.querySelectorAll('select');
var instances = M.FormSelect.init(elems);
});
</script>
<!-- Compiled and minified CSS -->
<link rel="stylesheet" href="{% static "main/css/materialize.css" %}">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
</head>
<body>
<nav>
<div class="nav-wrapper"
<ul id="nav-mobile" class="right hide-on-med-and-down">
{% include 'main/includes/navbar.html' %}
</ul>
</div>
</nav>
{% include 'main/includes/messages.html' %}
<div class="container">
{% block content %}
{% endblock %}
</div>
</body>
<script src="{% static "tinymce/js/prism.js" %}"></script>
<script>M.AutoInit();</script>
product_form.html
{% block content %}
<h2>Product Form</h2>
<form method="POST" id="productForm" data-plants-url="{% url 'ajax_load_plants' %}" data-business-url="{% url 'ajax_load_businesses' %}" novalidate>
{% csrf_token %}
<table>
{{ form.as_table }}
</table>
<button class="btn-small waves-effect waves-light" type="submit" name="action">Submit
<i class="material-icons right">send</i>
</button>
<a class="waves-effect waves-light btn-small" href="{% url 'product_changelist' %}">Cancel</a>
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
$("#id_country").change(function () {
var url = $("#productForm").attr("data-business-url");
var countryId = $(this).val();
$.ajax({
url: url,
data: {
'country': countryId
},
success: function (data) {
$("#id_business_unit").html(data);
$("#id_business_unit").change(function () {
var url2 = $("#productForm").attr("data-plants-url");
var business_unitId = $(this).val();
$.ajax({
url: url2,
data: {
'business_unit': business_unitId
},
success: function (data) {
$("#id_plant").html(data);
}
});
});
}
});
});
</script>
{% endblock %}
drop_down_options-businessunit.html
{% for business in business_units %}
<option class=browser-default value="{{ business.pk }}">{{ business.name }}</option>
{% endfor %}
drop_down_options-plant.html
<option value="" disabled selected>---------</option>
{% for plant in plants %}
<option class=browser-default value="{{ plant.pk }}">{{ plant.name }}</option>
{% endfor %}
Python
models.py
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Country(models.Model):
name = models.CharField(max_length = 50, default="")
def __str__(self):
return self.name
class Business_Unit(models.Model):
country = models.ForeignKey(Country, on_delete=models.CASCADE)
name = models.CharField(max_length = 50)
def __str__(self):
return self.name
class Plant(models.Model):
country = models.ForeignKey(Country, on_delete=models.CASCADE)
business_unit = models.ForeignKey(Business_Unit, on_delete=models.CASCADE)
name = models.CharField(max_length = 50)
def __str__(self):
return self.name
class Product(models.Model):
country = models.ForeignKey(Country, on_delete=models.SET_NULL, null=True)
business_unit = models.ForeignKey(Business_Unit, on_delete=models.SET_NULL, null=True)
plant = models.ForeignKey(Plant, on_delete=models.SET_NULL, null=True)
name = models.CharField(max_length = 200)
class Meta:
unique_together = [['country','business_unit','plant']]
def __str__(self):
return self.name
views.py
from django.shortcuts import get_object_or_404, render, redirect
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.contrib.auth.forms import AuthenticationForm
from django.views.generic import ListView, CreateView, UpdateView
from django.urls import reverse_lazy
from django.contrib import messages
from .models import Country, Business_Unit, Plant, Product
from .forms import NewUserForm, productForm
class ProductListView(ListView):
model = Product
context_object_name = 'product'
class ProductSearchView(CreateView):
model = Product
form_class = productForm
success_url = reverse_lazy('product_changelist')
class ProductCreateView(CreateView):
model = Product
form_class = productForm
#fields = ('name', 'country', 'business_unit', 'plant')
success_url = reverse_lazy('product_changelist')
class ProductUpdateView(UpdateView):
model = Product
form_class = productForm
#fields = ('name', 'country', 'business_unit', 'plant')
success_url = reverse_lazy('product_changelist')
def load_businesses(request):
country_id = request.GET.get('country')
business_units = Business_Unit.objects.filter(country_id=country_id).order_by('name')
return render(request, 'main/drop_down_options-businessunit.html', {'business_units': business_units})
def load_plants(request):
business_unit_id = request.GET.get('business_unit')
plants = Plant.objects.filter(business_unit_id=business_unit_id).order_by('name')
return render(request, 'main/drop_down_options-plant.html', {'plants': plants})
forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from .models import Business_Unit, Product, Plant
class productForm(forms.ModelForm):
class Meta:
model = Product
fields = ('name', 'country', 'business_unit', 'plant')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['business_unit'].queryset = Business_Unit.objects.none()
self.fields['plant'].queryset = Plant.objects.none()
if 'country' in self.data:
try:
country_id = int(self.data.get('country'))
self.fields['business_unit'].queryset = Business_Unit.objects.filter(country_id=country_id).order_by('name')
except (ValueError, TypeError):
pass # invalid input from the client; ignore and fallback to empty plant queryset
elif self.instance.pk:
self.fields['business_unit'].queryset = self.instance.country.business_unit_set.order_by('name')
if 'business_unit' in self.data:
try:
business_unit = int(self.data.get('business_unit'))
self.fields['plant'].queryset = Plant.objects.filter(business_unit=business_unit).order_by('name')
except (ValueError, TypeError):
pass # invalid input from the client; ignore and fallback to empty plant queryset
elif self.instance.pk:
self.fields['plant'].queryset = self.instance.country.plant_set.order_by('name')
urls.py
from django.urls import path,include
from django.contrib import admin
from . import views
from .views import profile
urlpatterns = [
path('',views.login_request, name="login"),
path('main/', views.ProductListView.as_view(), name='product_changelist'),
path('add/', views.ProductCreateView.as_view(), name='product_add'),
path('search/', views.ProductSearchView.as_view(), name='product_search'),
path('<int:pk>/', views.ProductUpdateView.as_view(), name='product_change'),
path('ajax/load-businesses/', views.load_businesses, name='ajax_load_businesses'),
path('ajax/load-plants/', views.load_plants, name='ajax_load_plants'),
]
Однако любая помощь будет принята с благодарностью. И я надеюсь, что я могу уточнить все, что запутано / упущено. Спасибо!