如何在Django CRUD应用中创建关联下拉列表(求完整代码)
Django CRUD 应用完整实现(关联州/城市 + 水平表单布局)
以下是满足需求的完整代码实现,包含州与城市的联动、水平表单布局及完整的CRUD功能:
1. 项目初始化(若未完成)
执行以下命令创建项目和应用:
django-admin startproject crud_project cd crud_project python manage.py startapp company
将company应用添加到crud_project/settings.py的INSTALLED_APPS中:
INSTALLED_APPS = [ # 原有应用 'company', ]
2. 模型定义 (company/models.py)
定义关联的州、城市及公司模型:
from django.db import models class State(models.Model): name = models.CharField(max_length=100, unique=True) def __str__(self): return self.name class City(models.Model): state = models.ForeignKey(State, on_delete=models.CASCADE, related_name='cities') name = models.CharField(max_length=100) class Meta: unique_together = ('state', 'name') def __str__(self): return self.name class Company(models.Model): company_name = models.CharField(max_length=200) dob = models.DateField() date_time = models.DateTimeField() state = models.ForeignKey(State, on_delete=models.PROTECT) city = models.ForeignKey(City, on_delete=models.PROTECT) def __str__(self): return self.company_name
执行迁移命令:
python manage.py makemigrations python manage.py migrate
3. 表单定义 (company/forms.py)
创建支持联动和样式的模型表单:
from django import forms from .models import Company, State, City class CompanyForm(forms.ModelForm): class Meta: model = Company fields = ['company_name', 'dob', 'date_time', 'state', 'city'] widgets = { 'dob': forms.DateInput(attrs={'type': 'date', 'class': 'form-control'}), 'date_time': forms.DateTimeInput(attrs={'type': 'datetime-local', 'class': 'form-control'}), 'company_name': forms.TextInput(attrs={'class': 'form-control'}), 'state': forms.Select(attrs={'class': 'form-control', 'id': 'state-select'}), 'city': forms.Select(attrs={'class': 'form-control', 'id': 'city-select'}), } def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # 编辑页面时,自动加载对应州的城市 if self.instance.pk: state_id = self.instance.state_id self.fields['city'].queryset = City.objects.filter(state_id=state_id) else: self.fields['city'].queryset = City.objects.none()
4. 视图函数 (company/views.py)
实现CRUD逻辑及AJAX城市加载接口:
from django.shortcuts import render, get_object_or_404, redirect from django.http import JsonResponse from .models import Company, State, City from .forms import CompanyForm def company_list(request): companies = Company.objects.all() return render(request, 'company/company_list.html', {'companies': companies}) def company_create(request): if request.method == 'POST': form = CompanyForm(request.POST) if form.is_valid(): form.save() return redirect('company_list') else: form = CompanyForm() return render(request, 'company/company_form.html', {'form': form}) def company_update(request, pk): company = get_object_or_404(Company, pk=pk) if request.method == 'POST': form = CompanyForm(request.POST, instance=company) if form.is_valid(): form.save() return redirect('company_list') else: form = CompanyForm(instance=company) return render(request, 'company/company_form.html', {'form': form}) def company_delete(request, pk): company = get_object_or_404(Company, pk=pk) if request.method == 'POST': company.delete() return redirect('company_list') return render(request, 'company/company_confirm_delete.html', {'company': company}) # AJAX接口:根据州ID加载对应城市 def load_cities(request): state_id = request.GET.get('state_id') cities = City.objects.filter(state_id=state_id).order_by('name') return JsonResponse(list(cities.values('id', 'name')), safe=False)
5. URL配置
项目URL (crud_project/urls.py)
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('', include('company.urls')), ]
应用URL (company/urls.py)
创建该文件并添加:
from django.urls import path from . import views urlpatterns = [ path('', views.company_list, name='company_list'), path('create/', views.company_create, name='company_create'), path('update/<int:pk>/', views.company_update, name='company_update'), path('delete/<int:pk>/', views.company_delete, name='company_delete'), path('load-cities/', views.load_cities, name='load_cities'), ]
6. 模板文件
创建templates/company目录,添加以下模板:
company_list.html(列表页面)
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>公司列表</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css"> </head> <body> <div class="container mt-4"> <h2>公司列表</h2> <a href="{% url 'company_create' %}" class="btn btn-primary mb-3">添加新公司</a> <table class="table table-striped"> <thead> <tr> <th>公司名称</th> <th>成立日期</th> <th>记录时间</th> <th>所属州</th> <th>所属城市</th> <th>操作</th> </tr> </thead> <tbody> {% for company in companies %} <tr> <td>{{ company.company_name }}</td> <td>{{ company.dob }}</td> <td>{{ company.date_time }}</td> <td>{{ company.state.name }}</td> <td>{{ company.city.name }}</td> <td> <a href="{% url 'company_update' company.pk %}" class="btn btn-sm btn-info">编辑</a> <a href="{% url 'company_delete' company.pk %}" class="btn btn-sm btn-danger">删除</a> </td> </tr> {% endfor %} </tbody> </table> </div> </body> </html>
company_form.html(创建/编辑共用,水平布局)
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>{% if form.instance.pk %}编辑公司{% else %}添加公司{% endif %}</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css"> </head> <body> <div class="container mt-4"> <h2>{% if form.instance.pk %}编辑公司{% else %}添加新公司{% endif %}</h2> <form method="post"> {% csrf_token %} <!-- 第一行:公司名称、成立日期、记录时间 --> <div class="form-row"> <div class="form-group col-md-4"> <label for="{{ form.company_name.id_for_label }}">公司名称</label> {{ form.company_name }} {% if form.company_name.errors %} <small class="text-danger">{{ form.company_name.errors.0 }}</small> {% endif %} </div> <div class="form-group col-md-4"> <label for="{{ form.dob.id_for_label }}">成立日期</label> {{ form.dob }} {% if form.dob.errors %} <small class="text-danger">{{ form.dob.errors.0 }}</small> {% endif %} </div> <div class="form-group col-md-4"> <label for="{{ form.date_time.id_for_label }}">记录时间</label> {{ form.date_time }} {% if form.date_time.errors %} <small class="text-danger">{{ form.date_time.errors.0 }}</small> {% endif %} </div> </div> <!-- 第二行:州、城市 --> <div class="form-row"> <div class="form-group col-md-6"> <label for="{{ form.state.id_for_label }}">所属州</label> {{ form.state }} {% if form.state.errors %} <small class="text-danger">{{ form.state.errors.0 }}</small> {% endif %} </div> <div class="form-group col-md-6"> <label for="{{ form.city.id_for_label }}">所属城市</label> {{ form.city }} {% if form.city.errors %} <small class="text-danger">{{ form.city.errors.0 }}</small> {% endif %} </div> </div> <button type="submit" class="btn btn-primary">保存</button> <a href="{% url 'company_list' %}" class="btn btn-secondary ml-2">取消</a> </form> </div> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <script> $(document).ready(function() { // 监听州选择变化,动态加载对应城市 $('#state-select').change(function() { var stateId = $(this).val(); if (stateId) { $.ajax({ url: '{% url "load_cities" %}', data: {'state_id': stateId}, dataType: 'json', success: function(data) { $('#city-select').empty(); $('#city-select').append('<option value="">选择城市</option>'); $.each(data, function(index, city) { $('#city-select').append('<option value="' + city.id + '">' + city.name + '</option>'); }); } }); } else { $('#city-select').empty(); $('#city-select').append('<option value="">请先选择州</option>'); } }); }); </script> </body> </html>
company_confirm_delete.html(删除确认页面)
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>删除公司</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css"> </head> <body> <div class="container mt-4"> <h2>确定要删除 "{{ company.company_name }}" 吗?</h2> <form method="post"> {% csrf_token %} <button type="submit" class="btn btn-danger">确认删除</button> <a href="{% url 'company_list' %}" class="btn btn-secondary ml-2">取消</a> </form> </div> </body> </html>
7. 初始化测试数据(可选)
创建company/fixtures/states_cities.json文件:
[ {"model": "company.state", "pk": 1, "fields": {"name": "Karnataka"}}, {"model": "company.city", "pk": 1, "fields": {"state": 1, "name": "Bangalore"}}, {"model": "company.city", "pk": 2, "fields": {"state": 1, "name": "Mysore"}} ]
执行命令加载数据:
python manage.py loaddata states_cities.json
8. 运行项目
python manage.py runserver
访问http://localhost:8000即可使用完整的CRUD功能。
内容的提问来源于stack exchange,提问作者magib977
相关产品推荐
相关产品推荐

