Django如何根据以其他形式选择的父外键来过滤外键?

问题描述 投票:1回答:1

我正在尝试为编辑表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 %}
python django forms
1个回答
0
投票

这是我的主张:已测试

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)
© www.soinside.com 2019 - 2024. All rights reserved.