我正在尝试为编辑表Person创建一个表单,但是在此表单字段中,必须由选定的Company过滤Car。我是python / django的新手,所以这可能是一个不好的方法,欢迎高级建议。这是我所拥有的:
我在models.py中有3个模型:
from django.db import models
class Company(models.Model):
company = models.CharField(max_length=25)
def __str__(self):
return self.company
class Car(models.Model):
car = models.CharField(max_length=25)
company = models.ForeignKey(Company, on_delete = models.CASCADE)
def __str__(self):
return self.car
class Person(models.Model):
name = models.CharField(max_length=20)
car = models.ForeignKey(Car, on_delete = models.CASCADE)
def __str__(self):
return self.name
views.py:
def index(request):
people = Person.objects.all().select_related('car__company')
table = PersonTable(people)
return render(request, 'index.html', {'table': table})
def edit(request, id):
person = Person.objects.get(id = id)
car = Car.objects.get(id = person.car_id)
company = Company.objects.get(id = car.company_id)
if request.method == 'POST':
form = PersonForm(car.company_id, request.POST, instance=person)
if form.is_valid():
form.save()
return redirect('/person/')
else:
companys = CompanyForm(instance=company)
form = PersonForm(car.company_id, instance=person)
return render(request, 'person/edit.html', {'companys':companys, 'form':form})
def Company_select(request):
if request.method == 'POST':
form = CompanySelectForm(request.POST)
if form.is_valid:
return redirect('/person/edit/1/') # Return to form PersonForm with id=1.
# How to return selected Company?
# How to return to page with other id?
else:
form = CompanySelectForm()
return render(request, 'person/company_select.html', {'form':form})
urls.py:
app_name = 'person'
urlpatterns = [
path('edit/<int:id>/', views.edit),
path('company/', views.Company_select, name='company'),
path('', views.index),
]
forms.py
class CompanyForm(forms.ModelForm):
class Meta:
model = Company
fields = ('company',)
class CompanySelectForm(forms.Form):
company = forms.ModelChoiceField(queryset=Company.objects.all().order_by('company'))
class Meta:
fields = ('company',)
class PersonForm(forms.ModelForm):
class Meta:
model = Person
fields = ('name', 'car',)
def __init__(self, company, *args, **kwargs):
super(PersonForm, self).__init__(*args, **kwargs)
self.fields['car'].queryset = Car.objects.filter(company=company) #Filter by Company
edit.html
{% extends "base.html" %}
{% block header %}Edit{% endblock header %}
{% block content%}
<form action="" method="post">
{% csrf_token %}
{{ form.as_table }}
{{ companys.as_table }}
<a href="/person/company/"><button type="button" class="btn btn-default btn-xs">Select Company</button></a>
<button class="btn btn-primary" type="submit" name="submit">submit</button>
</form>
{% endblock content %}
company_select.html
{% extends "base.html" %}
{% block header %}Select Company{% endblock header %}
{% block content%}
<form action="" method="post">
{% csrf_token %}
{{ form.as_table }}
<button class="btn btn-primary" type="submit" name="submit">submit</button>
</form>
{% endblock content %}
这是我的主张:已测试
form.py =>添加将调用您.html中定义的JS函数的属性
class PersonForm(ModelForm):
class Meta:
model = Person
fields = ('name', 'company', 'car')
def __init__(self, *args, **kwargs,):
super(PersonForm, self).__init__(*args, **kwargs)
class SelectForm(Form):
name = CharField(label='name')
company = ChoiceField(label='company')
car = ChoiceField(label='car')
class Meta:
fields = ('name', 'company', 'car', )
def __init__(self, cars=None, *args, **kwargs, ):
super(SelectForm, self).__init__(*args, **kwargs)
self.fields['car'].choices = cars
self.fields['company'].choices = tuple(Company.objects.all().values_list(flat=False))
self.fields['company'].widget.attrs['onchange'] = "load_car()"
edit.html:=>定义JS函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form id='myform' method="POST">
{% csrf_token %}
{{ form }}
</form>
<button class="btn btn-primary" type="submit" name="submit">submit</button>
</body>
<script>
function load_car()
{
document.getElementById('myform').action = "/stack/myview";
document.getElementById("myform").submit();
}
</script>
</html>
Views.py:=>将在数据库中查找公司名称并返回到模板的新视图
def index(request): # RF configuration FORM
form = PersonForm()
content = {'form': form}
return render(request, 'stack/index.html', content)
def edit(request, my_id):
if request.method == 'POST':
form = PersonForm(request.POST)
if form.is_valid():
form.save()
# Do ....
return HttpResponseRedirect(reverse('stack:index'))
else:
person = Person.objects.values_list().get(id__exact=my_id)
cars = []
[cars.append((x['car'], x['car'])) for x in
list(Car.objects.filter(company__exact=person[2]).values('car'))]
form = SelectForm(cars=cars, initial={'name': person[1], 'company': person[2], 'car': person[3]})
content = {'form': form}
return render(request, 'stack/edit.html', content)
else:
person = Person.objects.values_list().get(id__exact=my_id)
cars = []
[cars.append((x['car'], x['car'])) for x in list(Car.objects.filter(company__exact=person[2]).values('car'))]
form = SelectForm(cars=cars, initial={'name': person[1], 'company': person[2], 'car': person[3]})
content = {'form': form}
return render(request, 'stack/edit.html', content)
def myview(request):
cars = []
[cars.append((x['car'], x['car'])) for x in list(Car.objects.filter(company__exact=request.POST['company']).
values('car'))]
form = SelectForm(cars=cars, initial={'name': request.POST['name'], 'company': request.POST['company'], 'car': None})
content = {'form': form}
return render(request, 'stack/edit.html', content)