提交 39f70bd3 编写于 作者: 骆昊的技术专栏's avatar 骆昊的技术专栏

更新了Django第4天代码

上级 a8428301
import pymysql
pymysql.install_as_MySQLdb()
\ No newline at end of file
"""
Django settings for car project.
Generated by 'django-admin startproject' using Django 2.0.5.
For more information on this file, see
https://docs.djangoproject.com/en/2.0/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.0/ref/settings/
"""
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'ol6dmf6im(w!l*z4w+_whm&)8@(c7%4&tlhd%uh6$lfx=pi*5e'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'search',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'car.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')]
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'car.wsgi.application'
# Database
# https://docs.djangoproject.com/en/2.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'car',
'HOST': 'localhost',
'PORT': 3306,
'USER': 'root',
'PASSWORD': '123456',
}
}
# Password validation
# https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/2.0/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.0/howto/static-files/
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
STATIC_URL = '/static/'
"""car URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/2.0/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.conf.urls import url
from search import views
urlpatterns = [
url(r'^search$', views.search),
url(r'^search2$', views.ajax_search),
url(r'^add', views.add),
url(r'^admin/', admin.site.urls),
]
"""
WSGI config for car project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/2.0/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "car.settings")
application = get_wsgi_application()
#!/usr/bin/env python
import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "car.settings")
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
from django.contrib import admin
from search.models import CarRecord
class CarRecordAdmin(admin.ModelAdmin):
list_display = ('carno', 'reason', 'date', 'punish', 'isdone')
search_fields = ('carno', )
admin.site.register(CarRecord, CarRecordAdmin)
from django.apps import AppConfig
class SearchConfig(AppConfig):
name = 'search'
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2018-05-24 01:16
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='CarRecord',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('carno', models.CharField(max_length=7)),
('reason', models.CharField(max_length=50)),
('date', models.DateTimeField(db_column='happen_date')),
('punlish', models.CharField(max_length=50)),
('isdone', models.BooleanField(default=False)),
],
options={
'db_table': 'tb_car_record',
},
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2018-05-24 06:20
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('search', '0001_initial'),
]
operations = [
migrations.AlterModelOptions(
name='carrecord',
options={'ordering': ('-date',)},
),
migrations.RenameField(
model_name='carrecord',
old_name='punlish',
new_name='punish',
),
]
from django.db import models
class CarRecord(models.Model):
carno = models.CharField(max_length=7)
reason = models.CharField(max_length=50)
date = models.DateTimeField(db_column='happen_date', auto_now_add=True)
punish = models.CharField(max_length=50)
isdone = models.BooleanField(default=False)
@property
def happen_date(self):
return self.date.strftime('%Y-%m-%d %H:%M:%S')
"""
return '%d年%02d月%02d日 %02d:%02d:%02d' % \
(self.date.year, self.date.month, self.date.day,
self.date.hour, self.date.minute, self.date.second)
"""
class Meta:
db_table = 'tb_car_record'
ordering = ('-date', )
from django.test import TestCase
# Create your tests here.
from json import JSONEncoder
from django import forms
from django.http import JsonResponse
from django.shortcuts import render
from search.models import CarRecord
# 序列化/串行化/腌咸菜 - 把对象按照某种方式处理成字节或者字符的序列
# 反序列化/反串行化 - 把字符或者字节的序列重新还原成对象
# Python实现序列化和反序列化的工具模块 - json / pickle / shelve
# return HttpResponse(json.dumps(obj), content_type='application/json')
# return JsonResponse(obj, encoder=, safe=False)
# from django.core.serializers import serialize
# return HttpResponse(serialize('json', obj), content_type='application/json; charset=utf-8')
class CarRecordEncoder(JSONEncoder):
def default(self, o):
del o.__dict__['_state']
o.__dict__['date'] = o.happen_date
return o.__dict__
def ajax_search(request):
if request.method == 'GET':
return render(request, 'search2.html')
else:
carno = request.POST['carno']
record_list = list(CarRecord.objects.filter(carno__icontains=carno))
# 第一个参数是要转换成JSON格式(序列化)的对象
# encoder参数要指定完成自定义对象序列化的编码器(JSONEncoder的子类型)
# safe参数的值如果为True那么传入的第一个参数只能是字典
# return HttpResponse(json.dumps(record_list), content_type='application/json; charset=utf-8')
return JsonResponse(record_list, encoder=CarRecordEncoder,
safe=False)
def search(request):
# 请求行中的请求命令
# print(request.method)
# 请求行中的路径
# print(request.path)
# 请求头(以HTTP_打头的键是HTTP请求的请求头)
# print(request.META)
# 查询参数: http://host/path/resource?a=b&c=d
# print(request.GET)
# 表单参数
# print(request.POST)
if request.method == 'GET':
ctx = {'show_result': False}
else:
carno = request.POST['carno']
ctx = {
'show_result': True,
'record_list': list(CarRecord.objects.filter(carno__contains=carno))}
return render(request, 'search.html', ctx)
class CarRecordForm(forms.Form):
carno = forms.CharField(min_length=7, max_length=7, label='车牌号', error_messages={'carno': '请输入有效的车牌号'})
reason = forms.CharField(max_length=50, label='违章原因')
punish = forms.CharField(max_length=50, required=False, label='处罚方式')
def add(request):
errors = []
if request.method == 'GET':
f = CarRecordForm()
else:
f = CarRecordForm(request.POST)
if f.is_valid():
CarRecord(**f.cleaned_data).save()
f = CarRecordForm()
else:
errors = f.errors.values()
return render(request, 'add.html', {'f': f, 'errors': errors})
<svg width="13" height="13" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg">
<path fill="#dd4646" d="M1277 1122q0-26-19-45l-181-181 181-181q19-19 19-45 0-27-19-46l-90-90q-19-19-46-19-26 0-45 19l-181 181-181-181q-19-19-45-19-27 0-46 19l-90 90q-19 19-19 46 0 26 19 45l181 181-181 181q-19 19-19 45 0 27 19 46l90 90q19 19 46 19 26 0 45-19l181-181 181 181q19 19 45 19 27 0 46-19l90-90q19-19 19-46zm387-226q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/>
</svg>
<svg width="13" height="13" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg">
<path fill="#70bf2b" d="M1412 734q0-28-18-46l-91-90q-19-19-45-19t-45 19l-408 407-226-226q-19-19-45-19t-45 19l-91 90q-18 18-18 46 0 27 18 45l362 362q19 19 45 19 27 0 46-19l543-543q18-18 18-45zm252 162q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/>
</svg>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>添加</title>
</head>
<body>
<h2>添加违章记录</h2>
<hr>
<p>
{% for err in errors %}
<div style="color: red; font-size: 12px;">{{ err }}</div>
{% endfor %}
</p>
<form action="/add" method="post">
<table>
{{ f.as_table }}
</table>
{% csrf_token %}
<input type="submit" value="添加">
</form>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
{% load staticfiles %}
<html lang="en">
<head>
<meta charset="UTF-8">
<title>车辆违章查询</title>
<style>
* {
font: 18px/30px Arial;
}
#container {
width: 960px;
margin: 0 auto;
}
#container form {
width: 620px;
margin: 10px auto;
padding-top: 100px;
}
#container form input[type=search] {
display: inline-block;
width: 480px;
height: 30px;
}
#container form input[type=submit] {
display: inline-block;
width: 80px;
height: 40px;
border: None;
background-color: red;
color: white;
margin-left: 20px;
}
#container table {
width: 920px;
margin: 20px auto;
border-collapse: collapse;
}
#container table th {
font-weight: bolder;
border-bottom: 1px solid darkgray;
}
#container table td {
text-align: center;
height: 50px;
width: 180px;
}
</style>
</head>
<body>
<div id="container">
<form action="/search" method="post">
<!-- 跨站身份伪造: 利用浏览器存储的cookie中的用户身份标识冒充用户执行操作 -->
<!-- 防范跨站身份伪造最佳的做法就是在表单中放置随机令牌 -->
<!-- 除此之外通过设置令牌还可以防范表单重复提交以及重放攻击 -->
<!-- 隐藏域 / 隐式表单域: 页面上是无法看到该内容-->
{% csrf_token %}
<input type="search" name="carno" placeholder="请输入你的车牌号" required>
<input type="submit" value="搜索">
</form>
<hr>
{% if show_result %}
<table>
<tr>
<th>车牌号</th>
<th>违章原因</th>
<th>违章时间</th>
<th>处罚方式</th>
<th>是否受理</th>
</tr>
{% for record in record_list %}
<tr>
<td>{{ record.carno }}</td>
<td>{{ record.reason }}</td>
<td>{{ record.happen_date }}</td>
<td>{{ record.punish }}</td>
<td>
{% if record.isdone %}
<img src="{% static '/images/icon-yes.svg' %}">
{% else %}
<img src="{% static '/images/icon-no.svg' %}">
{% endif %}
</td>
</tr>
{% endfor %}
</table>
{% endif %}
</div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>车辆违章查询</title>
<style>
* {
font: 18px/30px Arial;
}
#container {
width: 960px;
margin: 0 auto;
}
#search {
width: 720px;
margin: 10px auto;
padding-top: 100px;
}
#search input[type=search] {
display: inline-block;
width: 480px;
height: 30px;
}
#search input[type=submit] {
display: inline-block;
width: 80px;
height: 40px;
border: None;
background-color: red;
color: white;
margin-left: 20px;
}
#result {
width: 920px;
margin: 20px auto;
border-collapse: collapse;
}
#result th {
font-weight: bolder;
border-bottom: 1px solid darkgray;
}
#result td, #result th {
text-align: center;
height: 50px;
width: 180px;
}
</style>
</head>
<body>
<div id="container">
<form id="search" action="/search" method="post">
<!-- 跨站身份伪造: 利用浏览器存储的cookie中的用户身份标识冒充用户执行操作 -->
<!-- 防范跨站身份伪造最佳的做法就是在表单中放置随机令牌 -->
<!-- 除此之外通过设置令牌还可以防范表单重复提交以及重放攻击 -->
<!-- 隐藏域 / 隐式表单域: 页面上是无法看到该内容-->
{% csrf_token %}
<input type="search" id="carno" name="carno" placeholder="请输入你的车牌号" required>
<input type="submit" value="搜索">
<a href="/add">添加新记录</a>
</form>
<hr>
<table id="result">
<thead>
<tr>
<th>车牌号</th>
<th>违章原因</th>
<th>违章时间</th>
<th>处罚方式</th>
<th>是否受理</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script>
$(function() {
$('#search').on('submit', function(evt) {
evt.preventDefault();
var carno = $('#carno').val();
var token = $('#search input[type=hidden]').val()
$.ajax({
url: '/search2',
type: 'post',
data: {
'carno': carno,
'csrfmiddlewaretoken': token
},
dataType: 'json',
success: function(json) {
$('#result tbody').children().remove();
for (var i = 0; i < json.length; i += 1) {
var record = json[i];
var tr = $('<tr>').append($('<td>').text(record.carno))
.append($('<td>').text(record.reason))
.append($('<td>').text(record.date))
.append($('<td>').text(record.punish));
var imgName = record.isdone ? 'icon-yes.svg' : 'icon-no.svg';
tr.append($('<td>').append($('<img>').attr('src', '/static/images/' + imgName)));
$('#result tbody').append(tr);
}
}
});
});
});
</script>
</body>
</html>
\ No newline at end of file
# Generated by Django 2.0.5 on 2018-05-22 03:07
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Dept',
fields=[
('no', models.IntegerField(primary_key=True, serialize=False)),
('name', models.CharField(max_length=20)),
('location', models.CharField(max_length=10)),
],
options={
'db_table': 'tb_dept',
},
),
migrations.CreateModel(
name='Emp',
fields=[
('no', models.IntegerField(primary_key=True, serialize=False)),
('name', models.CharField(max_length=20)),
('job', models.CharField(max_length=10)),
('mgr', models.IntegerField(null=True)),
('sal', models.DecimalField(decimal_places=2, max_digits=7)),
('comm', models.DecimalField(decimal_places=2, max_digits=7, null=True)),
('dept', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='hrs.Dept')),
],
options={
'db_table': 'tb_emp',
},
),
]
# Generated by Django 2.0.5 on 2018-05-23 01:23
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('hrs', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='dept',
name='excellent',
field=models.BooleanField(default=0, verbose_name='是否优秀'),
),
migrations.AlterField(
model_name='dept',
name='location',
field=models.CharField(max_length=10, verbose_name='部门所在地'),
),
migrations.AlterField(
model_name='dept',
name='name',
field=models.CharField(max_length=20, verbose_name='部门名称'),
),
migrations.AlterField(
model_name='dept',
name='no',
field=models.IntegerField(primary_key=True, serialize=False, verbose_name='部门编号'),
),
migrations.AlterField(
model_name='emp',
name='comm',
field=models.DecimalField(blank=True, decimal_places=2, max_digits=7, null=True),
),
migrations.AlterField(
model_name='emp',
name='mgr',
field=models.IntegerField(blank=True, null=True),
),
]
# Generated by Django 2.0.5 on 2018-05-24 08:46
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('hrs', '0002_auto_20180523_0923'),
]
operations = [
migrations.AlterField(
model_name='emp',
name='mgr',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='hrs.Emp'),
),
]
......@@ -24,7 +24,8 @@ class Emp(models.Model):
no = models.IntegerField(primary_key=True)
name = models.CharField(max_length=20)
job = models.CharField(max_length=10)
mgr = models.IntegerField(null=True, blank=True)
mgr = models.ForeignKey('self', null=True, blank=True, on_delete=models.SET_NULL)
# mgr = models.IntegerField(null=True, blank=True)
sal = models.DecimalField(max_digits=7, decimal_places=2)
comm = models.DecimalField(max_digits=7, decimal_places=2, null=True, blank=True)
dept = models.ForeignKey(Dept, on_delete=models.PROTECT)
......
......@@ -4,6 +4,7 @@ from hrs import views
urlpatterns = [
path('depts', views.depts, name='depts'),
path('depts/emps', views.emps, name='empsindept'),
path('deldepts', views.del_dept, name='ddel')
# url('depts/emps/(?P<no>[0-9]+)', views.emps, name='empsindept'),
path('depts/emps/<int:no>', views.emps, name='empsindept'),
path('deldept/<int:no>', views.del_dept, name='ddel')
]
from django.http import HttpResponse
from django.shortcuts import render, redirect
from django.urls import reverse
from django.db.models import ObjectDoesNotExist
from json import dumps
from hrs.models import Dept, Emp
......@@ -11,13 +14,21 @@ def index(request):
return render(request, 'index.html', context=ctx)
def del_dept(request):
# 重定向 - 重新请求一个指定的页面
return redirect(reverse('depts'))
def del_dept(request, no='0'):
try:
Dept.objects.get(pk=no).delete()
ctx = {'code': 200}
except (ObjectDoesNotExist, ValueError):
ctx = {'code': 404}
return HttpResponse(
dumps(ctx), content_type='application/json; charset=utf-8')
# 重定向 - 给浏览器一个URL, 让浏览器重新请求指定的页面
# return redirect(reverse('depts'))
# return depts(request)
def emps(request):
no = request.GET['no']
def emps(request, no='0'):
# no = request.GET['no']
# dept = Dept.objects.get(no=no)
# ForeignKey(Dept, on_delete=models.PROTECT, related_name='emps')
# dept.emps.all()
......
......@@ -5,6 +5,11 @@
<meta charset="UTF-8">
<title>部门</title>
<link href="{% static 'css/bootstrap.min.css' %}" rel="stylesheet">
<style>
#dept td, #dept th {
text-align: center;
}
</style>
</head>
<body>
<div class="container">
......@@ -14,6 +19,7 @@
<hr>
</div>
</div>
<div class="row clearfix">
<div class="col-md-8 column">
<table id="dept" class="table table-striped table-hover">
......@@ -32,7 +38,7 @@
<td>{{ dept.no }}</td>
<td>
<!-- 写代码时要尽量避免使用硬编码(hard code) -->
<a href="{% url 'empsindept' %}?no={{ dept.no }}">{{ dept.name }}</a>
<a href="{% url 'empsindept' dept.no %}">{{ dept.name }}</a>
</td>
<td>{{ dept.location }}</td>
<td>
......@@ -43,7 +49,7 @@
{% endif %}
</td>
<td>
<a href="{% url 'ddel' %}?dno={{ dept.no }}" class="btn btn-xs btn-warning">删除</a>
<a id="{{ dept.no }}" href="javascript:void(0);" class="btn btn-xs btn-warning">删除</a>
</td>
</tr>
{% endfor %}
......@@ -60,6 +66,18 @@
$(function() {
$('#dept tbody tr:even').addClass('info');
$('#dept tbody tr:odd').addClass('warning');
$('#dept a[id]').on('click', function(evt) {
var a = $(evt.target);
if (confirm('确定要删除吗?')) {
$.getJSON('/hrs/deldept/' + a.attr('id'), function(json) {
if (json.code == 200) {
a.parent().parent().remove();
$('#dept tbody tr:even').addClass('info');
$('#dept tbody tr:odd').addClass('warning');
}
});
}
});
});
</script>
</body>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册