本文共 12797 字,大约阅读时间需要 42 分钟。
`搭建Django环境
cmd命令面板 django-admin startproject carsys_1
创建虚拟环境和下载依赖
pycharm中新建虚拟环境,在虚拟环境中下载依赖,pip install django==2.2.12 pip install mysqlcliectpip intall Pillow
创建Django应用
python manage.py startapp serach
创建模板文件夹
根目录下创建 templates文件夹
创建静态资源文件夹
根目录下创建static文件夹 存放css、js、images
修改settings.py配置文件
TEMPLATES = [{ 'DIRS': [os.path.join(BASE_DIR,'templates')] #模板存放的路径,}]LANGUAGE_CODE = 'zh-hans' #汉化djangoTIME_ZONE = 'Asia/Shanghai' #设置时区INSTALLED_APPS = [ 'serach #应用路径] STATICFILES_DIRS = [os.path.join(BASE_DIR,'static'),] #静态资源存放路径
创建数据库sql语句
create database `carsys` default charset utf8;use `carsys`;create table `tb_car` ( `no` int(11) not null auto_increment, `carno` varchar(10) unique not null, `owner` varchar(20) not null, `brand` varchar(20) not null, primary key (`no`));create table `tb_record` ( `no` integer not null AUTO_INCREMENT, `reason` varchar(200) not null, `punish` varchar(200) not null, `makedate` date not null, `dealt` boolean default 0, `car_id` integer not null, `is_deleted` boolean default 0, `deleted_time` datetime, `updated_time` datetime, primary key (`no`), foreign key (`car_id`) references `tb_car` (`no`));insert into `tb_car` (`no`, `carno`, `owner`, `brand`)values (1,'川A12345','王大锤','QQ'), (2,'川A250SS','白元芳','Benz'), (3,'川B52088','狄仁杰','BMW'), (4,'川A54321','张小虎','Auto'), (5,'川B203T5','张佩琪','RR'), (6,'川AN9980','李乔治','Jetta'), (7,'川A13788','李佩佩','Swift');insert into `tb_record` (`is_deleted`, `deleted_time`, `updated_time`, `no`, `reason`, `punish`, `makedate`, `dealt`, `car_id`)values (0,NULL,NULL,1,'逆向行驶','扣3分,罚款500元','2019-01-01 00:00:00.000000',0,1), (0,NULL,NULL,2,'超速行驶','扣2分,罚款300元','2019-01-10 00:00:00.000000',0,2), (0,NULL,NULL,3,'违章停车','罚款100元','2019-03-15 00:00:00.000000',0,1), (0,NULL,NULL,4,'殴打交警','吊销驾照,拘留15天','2019-04-01 00:00:00.000000',0,1), (0,NULL,NULL,5,'酒驾','扣6分','2019-01-10 00:00:00.000000',0,3), (0,NULL,NULL,6,'醉驾','扣12分,罚款3000元','2019-01-20 00:00:00.000000',0,4), (0,NULL,NULL,7,'逆向行驶','扣3分,罚款500元','2018-12-15 00:00:00.000000',0,1), (0,NULL,NULL,8,'殴打交警','吊销驾照,拘留15天','2019-04-01 00:00:00.000000',0,2), (0,NULL,NULL,9,'酒驾','扣6分','2019-01-10 00:00:00.000000',0,4), (0,NULL,NULL,10,'醉驾','扣12分,罚款3000元','2019-01-20 00:00:00.000000',0,3), (0,NULL,NULL,11,'逆向行驶','扣3分,罚款500元','2018-12-15 00:00:00.000000',0,5), (0,NULL,NULL,12,'逆向行驶','扣3分,罚款500元','2018-07-23 00:00:00.000000',0,7), (0,NULL,NULL,13,'遮挡车牌','扣6分','2019-05-10 00:00:00.000000',0,5), (0,NULL,NULL,14,'超速行驶','扣2分,罚款300元','2018-10-30 00:00:00.000000',0,6);create user 'hellokitty'@'%' identified by '密码';grant all privilegs on carsys.* to 'hellokitty'@'%';flush privileges;
修改settings.py中数据库配置
DATABASE = { 'default':{ 'ENGINE': 'django.db.backends.mysql', 'NAME': 'vote', 'HOST':'服务器地址', 'PORT':3306, 'USER':'hellokitty', 'PASSWORD':'数据库密码', 'CHARSET':'utf8', 'TIME_ZONE':'Asia/Shanghai'}}
准备静态templates模板
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>违章查询</title> <style> #result>table{ border-collapse: collapse; } #result th { border-bottom:1px solid black; } #result td { text-align: center; height: 30px; border-bottom: 1px dashed darkgray; } #result tr:last-child > td{ border: none; } </style></head><body> <div id="result"> <form id="search" action="/search/" method="post"> {% csrf_token %} <input type="text" name="carinfo" value="{ { carinfo }}" size="30" placeholder="请输入车牌号或车主姓名"> <input type="submit" value="查询"> </form> <hr> {% if records %} <table> <tr> <th width="100">车牌号</th> <th width="100">车主姓名</th> <th width="150">违章原因</th> <th width="180">违章时间</th> <th width="180">处罚方式</th> <th width="100">是否受理</th> <th width="120">操作</th> </tr> {% for record in records %} <tr> <td>{ { record.car.carno }}</td> <td>{ { record.car.owner }}</td> <td>{ { record.reason }}</td> <td>{ { record.makedate }}</td> <td>{ { record.punish }}</td> <td>{ { record.dealt | yesno:'已受理,未受理' }}</td> <td> <a class="handle" href="/handle/?rno={ { record.no }}">受理</a> <a class="delete" href="/delete/?rno={ { record.no }}">删除</a> </td> </tr> {% endfor %} </table> <div class="buttons"> <button data="/search/?page=1&size={ { page_size }}">首页</button> {% if has_prev %}<button data="/search/?page={ { prev_page }}&size={ { page_size }}">上一页</button> {% else %}<button disabled>上一页</button> {% endif %} 第{ { current_page }}页/共{ { total_page }}页 {% if has_next %}<button data="/search/?page={ { next_page }}&size={ { page_size }}">下一页</button> {% else %}<button disabled>下一页</button> {% endif %} <button data="/search/?page={ { total_page }}&size={ { page_size }}">末页</button> </div> {% endif %} </div> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script> function loadPageData(evt) { $('#search').attr( 'action', $(evt.target).attr('data') ).trigger('submit') } $(() => { $('#export').on('click', (evt) => { evt.preventDefault() let url = $(evt.target).attr('href') let queryParam = '?carinfo=' + $('input[name="carinfo"]').val() location.href = url + queryParam }) $('.buttons>button').on('click', loadPageData) $('.handle').on('click', (evt) => { evt.preventDefault() let url = $(evt.target).attr('href') $.getJSON(url, (json) => { if (json.code === 30000) { $(evt.target).parent().prev().text('已受理') }else{ alert(json.mesg) } }) }) $('.delete').on('click', (evt) => { evt.preventDefault() if (confirm('确定删除该记录吗?')) { let url = $(evt.target).attr('href') $.getJSON(url, (json) => { if (json.code === 40000) { $(evt.target).parent().parent().remove() } else { alert(json.mesg) } }) } }) }) </script></body></html>
映射数据表(反向工程)
python mange.py inspectdb > search/models.py
models.py中的模型
from django.db import modelsclass Car(models.Model): no = models.AutoField(primary_key=True) carno = models.CharField(unique=True, max_length=10) owner = models.CharField(max_length=20) brand = models.CharField(max_length=20) class Meta: managed = False db_table = 'tb_car'class Record(models.Model): no = models.AutoField(primary_key=True) reason = models.CharField(max_length=200) punish = models.CharField(max_length=200) makedate = models.DateField() dealt = models.IntegerField(blank=True,default=False) car = models.ForeignKey(to=Car, on_delete=models.DO_NOTHING,db_column='car_id') #db_column='car_id 是对应到数据库那个字段,属性名不一致时需要指定 #on_delete=models.DO_NOTHING 删除数据时根据数据库的设置删除 is_deleted = models.BooleanField(blank=True,default=False) deleted_time = models.DateTimeField(blank=True, null=True) updated_time = models.DateTimeField(blank=True, null=True) #blank=True后admin后台填写是可以为空,不写就是不能为空 class Meta: managed = False db_table = 'tb_record' #需要后台管理的话,注册模型,模型迁移,这里不做模型
修改views.py
from django.http import HttpResponse, HttpRequestfrom django.shortcuts import renderfrom search.models import Recorddef index(request:HttpRequest) ->HttpResponse:"""首页""" return render(request,'index.html')def search(request:HttpRequest) ->HttpResponse:"""查询所有记录""" queryset = Record.objects.all() return render(request,'index.html',{ 'records':queryset })
修改urls.py
from django.contrib import adminfrom django.urls import pathfrom search.views import search,indexurlpatterns = [ path('admin/', admin.site.urls), path('search/',search), path('',index)]#做完此步可以查询所有记录
模糊查询
import refrom django.db.models import Qfrom django.http import HttpResponse, HttpRequestfrom django.shortcuts import renderfrom search.models import Recorddef index(request:HttpRequest) ->HttpResponse: return render(request,'index.html') #首页def search(request:HttpRequest) ->HttpResponse: queryset = Record.objects.all() carinfo = request.POST.get('carinfo') if carinfo: carinfo = re.sub(r'\s','',carinfo) #正则去掉空格 queryset = queryset.filter( Q(car__carno__istartswith=carinfo) | Q(car__owner__icontains=carinfo) ) """ 如果写两次filter为and关系 例如:queryset.filter(car__carno__istartswith=carinfo).filter(...) 如果想用 与或非 的条件可以导入Django模块下 Q 模块 & 而且关系 类似与and | 或者关系 类似与or ~ not 关系 not格式为:~Q(条件) 格式:Q(条件1)Q(条件2) car__carno 或 car__carno__exact 精确查询car对象里面carno属性,因为是外键所以可以拿到车牌号) car__carno__istartswith 模糊查询 例如输入'川A123'会得到'川A123%',后面加%。加i表示忽略大小写 car__carno__endswith 模糊查询 例如输入'川A123'会得到'%川A123',前面加% 。加i表示忽略大小写 car__carno__contains 模糊查询 例如输入'川A123'会得到'%川A123%',前后都加%。加i表示忽略大小写 一般外键查询格式为:有外键的表__参照的表字段__查询方法 """ return render(request,'index.html',{ 'records':queryset })
分页查询
url中?后面的参数通过request.GET --> []/get() 获取参数以post方式提交的表单数据使用request.POST -->[]/get 获取参数如果表单中上传了文件 request.FILES --> [].get() 获取参数 修改search视图函数def search(request:HttpRequest) ->HttpResponse: page = int(request.GET.get('page','1')) size = int(request.GET.get('size','5')) queryset = Record.objects.filter(is_deleted=False)\ .defer('is_deleted','deleted_time','updated_time')\ .select_related('car')#1对1、多对1外键关联可以通过select_related('关联对象')解决1+N查询问题#多对多外键关联通过prefetch_related('关联对象')解决1+N查询问题#defer(字段名)不查那些字段#only(字段名)查询那些字段 carinfo = request.POST.get('carinfo') if carinfo: carinfo = re.sub(r'\s','',carinfo) #正则去掉空格 queryset = queryset.filter( Q(car__carno__istartswith=carinfo) | Q(car__owner__icontains=carinfo) ) count = queryset.count() queryset = queryset.order_by('-makedate')[(page - 1) * size:page * size] total_page = (count - 1) // size +1 #总页数 return render(request,'index.html',{ 'records':queryset, #违章记录 'current_page':page, #当前页码 'total_page':total_page, #总页数 'has_prev': page > 1, #有没有上一页 'has_next':page < total_page, #有没有下一页 'prev_page':page - 1, #上一页页码 'next_page':page + 1, #下一页页码 'page_size':size, #页面大小 'carinfo':carinfo #查询条件 })#Django官方封装的分页器:https://docs.djangoproject.com/en/2.2/topics/pagination/
Ajax异步请求完成受理和删除
views.py中添加受理和删除的函数def handle_record(request: HttpRequest) -> HttpResponse: try: rno = int(request.GET.get('rno', '')) except ValueError: date = {'code':30002,'mesg':'违章记录编号无效'} else: record = Record.objects.filter(no=rno,dealt=False).first() if record and not record.dealt: record.dealt = True record.updated_time = timezone.now() record.save() date = {'code':30000,'mesg':'受理成功'} else: date = {'code':30001,'mesg':'受理失败'} return JsonResponse(date)def delete_record(request: HttpRequest) -> HttpResponse: try: rno = int(request.GET.get('rno','')) except ValueError: date = {'code':40002,'mesg':'违章记录编号无效'} else: record = Record.objects.filter(no=rno,is_deleted=False).first() if record: if record.dealt: record.is_deleted = True record.deleted_time = timezone.now() record.save() date = {'code':40000,'mesg':'删除成功'} else: date = {'code':40003,'mesg':'不能删除尚未受理的记录'} else: date = {'code':40001,'mesg':'删除失败'} return JsonResponse(date)urls.py中增加这个urlpath('handle/','handle_record),path('delete/',delete_record),
转载地址:http://xrqh.baihongyu.com/