让我们考虑以下模型
models.py
Class Brand(models.Model):
company_name = models.CharField(max_length=100)
class CarModel(models.Model):
brand = models.ForeignKey(Brand)
name = models.CharField(max_length=100)
Class FleetCars(models.Model):
model_car = models.Foreignkey(CarModel)
Run Code Online (Sandbox Code Playgroud)
在django中解决这个问题的最佳方法是什么?假设一个表单(用于FleetCars中的插入)由两个选择元素组成,如下所示:
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<br />Brand:
<select>
<option value="Brand1">Brand1</option>
<option value="Brand2">Brand2</option>
</select>
<br />
<br />Model:
<select>
<option value="Model1_B1">Model1_B1</option>
<option value="Model1_B2">Model1_B2</option>
</select>
</body>
</html>Run Code Online (Sandbox Code Playgroud)
在这种情况下,我希望第二个选项中的选项取决于在第一个选择中选择的值,例如,如果用户在第一个选择中为Brand选择了Brand1,则第二个选择将仅使用Brand为Brand1的汽车进行过滤,这只是"Model1_B1".
OBS.我看过很多带有forms.ModelChoiceField的解决方案,但只能用于编辑,因为用户不会改变品牌.
经过几个小时的研究,没有成功,我决定尝试自己解决.我找到的解决方案可能不是最好的或更优雅的,但是有效.(要下载完整的Django项目,请单击此repo => https://github.com/Sidon/djfkf/.)
models.py
from django.db import models
class Brand(models.Model):
company_name = models.CharField(max_length=100)
def __str__(self):
return self.company_name
class Car(models.Model):
brand = models.ForeignKey(Brand)
name = models.CharField(max_length=100)
def brand_name(self):
return self.brand.company_name
def __str__(self):
return self.name
class Fleet(models.Model):
car = models.ForeignKey(Car)
description = models.CharField(max_length=100)
def car_name(self):
return self.car.name
def brand(self):
return self.car.brand.company_name
def __str__(self):
return self.description
Run Code Online (Sandbox Code Playgroud)
目标是在车队登记汽车.将记录的唯一字段:Car(外键)和描述.在表单上,将有一个选择元素的品牌,只能作为过滤汽车的组合框的帮手.
forms.py
import json
from django import forms
from .models import *
class RegCarForm(forms.ModelForm):
dcars = {}
list_cars = []
for car in Car.objects.all():
if car.brand.company_name in dcars:
dcars[car.brand.company_name].append(car.name)
else:
dcars[car.brand.company_name] = [car.name]
list_cars.append((car.name,car.name))
brands = [str(brand) for brand in Brand.objects.all()]
brand_select = forms.ChoiceField(choices=([(brand, brand) for brand in brands]))
car_select = forms.ChoiceField(choices=(list_cars))
brands = json.dumps(brands)
cars = json.dumps(dcars)
class Meta:
model = Fleet
fields = ('brand_select', 'car_select', 'description',)
Run Code Online (Sandbox Code Playgroud)
RegCarForm是一个用于注册汽车的表单,有三个字段:brand_select,car_select和description.另外,我定义了两个JSON属性:1)一个字典,其键是品牌(字符串),值是各自汽车的列表,以及2)代表品牌的字符串列表.这两个属性将作为JS函数的助手.
views.py
from django.shortcuts import render
from .forms import RegCarForm
from .models import *
def regcar(request):
if request.method == 'POST':
car_form = RegCarForm(data=request.POST)
if car_form.is_valid():
cdata = car_form.cleaned_data.get
car_selected = Car.objects.filter(name=cdata('car_select'))
reg1 = Fleet(car_id=car_selected[0].id, description=cdata('description'))
reg1.save()
else:
print ('Invalid')
else:
car_form = RegCarForm()
return render(request, 'core/regcar.html', {'car_form': car_form})
Run Code Online (Sandbox Code Playgroud)
该视图几乎是自动解释的.将Form分配给car_form变量,渲染模板core/regcar.html,然后在Post之后,对表单进行验证并保存数据.
regcar.html(模板django)
{% extends "base.html" %}
{% block head %}
{% endblock %}
{% block content %}
<h1>Registering cars on the fleet. <br />(Populate one drop down based on selection in another)</h1>
<p>Change the contents of drop down Car based on the selection in dropdown Brand, using Django-forms + Javascritp</p>
<div class="select-style">
<form action="." method="post">
{% csrf_token %}
{{ car_form.as_p }}
<p><input type="submit" value="Register a car"></p>
</form>
</div>
{% endblock %}
{% block js %}
{% include "js1.html" %}
{% endblock %}
Run Code Online (Sandbox Code Playgroud)
该模板只是呈现表单并加载脚本JS.没有其他的.
最后,js脚本,这使得努力工作.
{% block js %}
<script language="javascript">
$('#id_brand_select').change(function() {populateCar(this)});
$('#id_description').addClass('descriptions');
cars = {{ car_form.cars | safe }}
brands = {{ car_form.brands | safe}};
populateBrand();
$("#id_car_select").empty();
$("#id_car_select").append('<option value="" disabled selected>First select a brand</option>');
function populateBrand() {
$('#id_brand_select').empty();
$("#id_brand_select").append('<option value="" disabled selected>Select your option</option>');
$.each(brands, function(v) {
$('#id_brand_select')
.append($("<option></option>")
.attr("value", brands[v])
.text(brands[v]));
});
}
function populateCar(event) {
brand = $("#id_brand_select option:selected").text();
$("#id_car_select").empty();
$("#id_car_select").append('<option value="" disabled selected>Select your option</option>');
for (let [b, bcars] of Object.entries(cars)) {
if (b == brand) {
//alert(b);
for (car in bcars) {
$('#id_car_select')
.append($("<option></option>")
.attr("value", bcars[car])
.text(bcars[car]));
}
}
}
}
</script>
{% endblock %}
Run Code Online (Sandbox Code Playgroud)
加载文档时,此脚本将brand_select的更改事件(用于选择品牌的组合)分配给函数poplulateCar,将表单的JASON属性(汽车和品牌)分配给JS变量并调用populateBrand函数.
Django的完整项目:https:
//github.com/Sidon/djfkf/
| 归档时间: |
|
| 查看次数: |
7664 次 |
| 最近记录: |