Commit 95c73fef authored by jackfrued's avatar jackfrued

修改了文档中的bug

parent 208cd3ee
"""
装饰器的应用
"""
from functools import wraps
from random import randint
from time import sleep
class Retry():
"""让函数可以重试执行的装饰器"""
def __init__(self, times=3, max_wait=0, errors=(Exception, )):
self.times = times
self.max_wait = max_wait
self.errors = errors
def __call__(self, func):
@wraps(func)
def wrapper(*args, **kwargs):
for _ in range(self.times):
try:
return func(*args, **kwargs)
except self.errors:
sleep(randint(self.max_wait))
return wrapper
def retry(*, times=3, max_wait=0, errors=(Exception, )):
"""让函数重试执行的装饰器函数"""
def decorate(func):
@wraps(func)
def wrapper(*args, **kwargs):
for _ in range(times):
try:
return func(*args, **kwargs)
except errors:
sleep(randint(max_wait))
return wrapper
return decorate
# @Retry(max_wait=5)
@retry(max_wait=5)
def get_data_from_url(url):
pass
"""
模拟面试编程题
"""
def second_max(items: list, gt=lambda x, y: x > y):
"""从列表中找出第二大元素"""
assert len(items) >= 2
max1, max2 = (items[0], items[1]) \
if gt(items[0], items[1]) else (items[1], items[0])
for i in range(2, len(items)):
if gt(max1, items[i]) and gt(items[i], max2):
max2 = items[i]
elif gt(items[i], max1):
max1, max2 = items[i], max1
return max2
def list_depth(items: list) -> int:
"""计算嵌套列表的嵌套深度"""
if isinstance(items, list):
max_depth = 1
for item in items:
max_depth = max(list_depth(item) + 1, max_depth)
return max_depth
return 0
def main():
"""主函数"""
one_set = {1}
pos, off = 1, 1
while pos <= 100000000:
pos += off
one_set.add(pos)
off += 1
num, *poses = map(int, input().split())
for pos in poses:
print(1 if pos in one_set else 0, end=' ')
# items1 = [38, 95, 27, 95, 88, 73, 61, 50]
# print(second_max(items1))
# items2 = [[1], [[[2]]],[[3]], 4, [[[[[5, [6]]]]]]]
# print(list_depth(items1))
# print(list_depth(items2))
if __name__ == '__main__':
main()
drop database if exists demo;
create database demo default charset utf8 collate utf8_general_ci;
use demo;
create table tb_teacher
(
teacherid int not null auto_increment,
tname varchar(20) not null,
tjob varchar(20) not null,
tintro varchar(1023) default '',
tmotto varchar(255) default '',
primary key (teacherid)
);
insert into tb_teacher (tname, tjob, tintro, tmotto) values
('骆昊', 'Python教学主管', '10年以上软硬件产品和系统设计、研发、架构和管理经验,2003年毕业于四川大学,四川大学Java技术俱乐部创始人,四川省优秀大学毕业生,在四川省网络通信技术重点实验室工作期间,参与了2项国家自然科学基金项目、1项中国科学院中长期研究项目和多项四川省科技攻关项目,在国际会议和国内顶级期刊上发表多篇论文(1篇被SCI收录,3篇被EI收录),大规模网络性能测量系统DMC-TS的设计者和开发者,perf-TTCN语言的发明者。国内最大程序员社区CSDN的博客专家,在Github上参与和维护了多个高质量开源项目,精通C/C++、Java、Python、R、Swift、JavaScript等编程语言,擅长OOAD、系统架构、算法设计、协议分析和网络测量,主持和参与过电子政务系统、KPI考核系统、P2P借贷平台等产品的研发,一直践行“用知识创造快乐”的教学理念,善于总结,乐于分享。', '教育是让受教育者体会用知识创造快乐的过程'),
('肖世荣', 'Python高级讲师', '10年以上互联网和移动互联网产品设计、研发、技术架构和项目管理经验,曾在中国移动、symbio、ajinga.com、万达信息等公司担任架构师、项目经理、技术总监等职务,长期为苹果、保时捷、耐克、沃尔玛等国际客户以及国内的政府机构提供信息化服务,主导的项目曾获得“世界科技先锋”称号,个人作品“许愿吧”曾在腾讯应用市场生活类App排名前3,拥有百万级用户群体,运营的公众号“卵石坊”是国内知名的智能穿戴设备平台。精通Python、C++、Java、Ruby、JavaScript等开发语言,主导和参与了20多个企业级项目(含国家级重大项目和互联网创新项目),涉及的领域包括政务、社交、电信、卫生和金融,有极为丰富的项目实战经验。授课深入浅出、条理清晰,善于调动学员的学习热情并帮助学员理清思路和方法。', '世上没有绝望的处境,只有对处境绝望的人'),
('余婷', 'Python高级讲师', '5年以上移动互联网项目开发经验和教学经验,曾担任上市游戏公司高级软件研发工程师和移动端(iOS)技术负责人,参了多个企业级应用和游戏类应用的移动端开发和后台服务器开发,拥有丰富的开发经验和项目管理经验,以个人开发者和协作开发者的身份在苹果的AppStore上发布过多款App。精通Python、C、Objective-C、Swift等开发语言,熟悉iOS原生App开发、RESTful接口设计以及基于Cocos2d-x的游戏开发。授课条理清晰、细致入微,性格活泼开朗、有较强的亲和力,教学过程注重理论和实践的结合,在学员中有良好的口碑。', '每天叫醒你的不是闹钟而是梦想'),
('王海飞', 'Python高级讲师', '5年以上Python开发经验,先后参与了O2O商城、CRM系统、CMS平台、ERP系统等项目的设计与研发,曾在全国最大最专业的汽车领域相关服务网站担任Python高级研发工程师、项目经理等职务,擅长基于Python、Java、PHP等开发语言的企业级应用开发,全程参与了多个企业级应用从需求到上线所涉及的各种工作,精通Django、Flask等框架,熟悉基于微服务的企业级项目开发,拥有丰富的项目实战经验。善于用浅显易懂的方式在课堂上传授知识点,在授课过程中经常穿插企业开发的实际案例并分析其中的重点和难点,通过这种互动性极强的教学模式帮助学员找到解决问题的办法并提升学员的综合素质。', '不要给我说什么底层原理、框架内核!老夫敲代码就是一把梭!复制!黏贴!拿起键盘就是干!'),
('何翰宇', 'JavaEE高级讲师', '5年以上JavaEE项目开发和教学经验,参与过人力资源管理系统、电子教育产品在线商城、平安好医生App、平安好车主App等项目的设计与研发。擅长Java语言、面向对象编程、JavaEE框架、Web前端开发、数据库编程和Android应用开发,对新技术有着浓厚的兴趣和钻研精神,对微服务架构、虚拟化技术、区块链、边缘计算等领域都有自己独到的认识和见解,有丰富的项目经验和教学经验。授课时注重学习方法的引导,提倡以项目为导向的实战型教学,同时也注重基础知识的掌握和底层原理的理解,课堂氛围轻松幽默,能够把枯燥乏味的知识变成生动有趣的案例,帮助学员更快更好的掌握技术的要领,从事JavaEE教学工作以来,获得了学生潮水般的好评。', '每天撸代码,生活乐无边!'),
('吴明富', 'HTML5教学主管', '毕业于西南交通大学,高级软件研发工程师,10年以上的开发和培训经验。曾就职于华为赛门铁克科技有限公司,负责公司内部ERP系统的研发,参与和主导过多个大型门户网站、电子商务网站、电子政务系统以及多个企业级Web项目的设计和开发,同时负责过多门企业内训课程的研发与讲授,有着非常丰富的JavaEE项目开发经验和Web前端开发经验,精通C/C++、Java、PHP、JavaScript等开发语言,能够使用多种技术进行全栈开发。授课经验丰富、思路清晰、富有激情,对知识点的讲解由浅入深、深入浅出,能够通过实际开发的场景引导学员思考业务并理解相关技术,善于将多年的项目实战经验和企业内训经验融入课堂,通过理论联系实际的方式帮助学员迅速提升就业能力。', '人生的道路在态度的岔口一分为二');
## 报表和日志 ## 报表和日志
###导出Excel报表 ### 导出Excel报表
报表就是用表格、图表等格式来动态显示数据,所以有人用这样的公式来描述报表: 报表就是用表格、图表等格式来动态显示数据,所以有人用这样的公式来描述报表:
......
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 datetime import datetime
from json import JSONEncoder
from django import forms
from django.http import JsonResponse
from django.shortcuts import render, redirect
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')
MAX_AGE = 14 * 24 * 60 * 60
class CarRecordEncoder(JSONEncoder):
def default(self, o):
del o.__dict__['_state']
o.__dict__['date'] = o.happen_date
return o.__dict__
def ajax_search(request):
current_time = datetime.now().ctime()
# Cookie是保存在浏览器临时文件中的用户数据(通常是识别用户身份的ID/token或者是用户的偏好设置)
# 因为每次请求服务器时在HTTP请求的请求头中都会携带本网站的Cookie数据
# 那么服务器就可以获取这些信息来识别用户身份或者了解用户的偏好 这就是所谓的用户跟踪
# 因为HTTP本身是无状态的 所以需要使用Cookie/隐藏域/URL重写这样的技术来实现用户跟踪
# 从请求中读取指定的cookie - 通过cookie的名字找到对应的值
# 如果请求中没有指定名字的cookie可以通过get方法的第二个参数设置一个默认的返回值
last_visit_time = request.COOKIES.get('last_visit_time')
if request.method == 'GET':
response = render(request, 'search2.html',
{'last': last_visit_time if last_visit_time
else '你是第一次访问我们的网站'})
# 通过render渲染页面后先用set_cookie方法设置cookie后再返回HttpResponse对象
# 第一个参数是cookie的名字 第二个参数是cookie的值 第三个参数是过期时间(秒)
response.set_cookie('last_visit_time', current_time, max_age=MAX_AGE)
return response
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.ModelForm):
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 clean_carno(self):
_carno = self.cleaned_data['carno']
if not condition:
raise forms.ValidationError('...')
return _carno
"""
class Meta:
model = CarRecord
fields = ('carno', 'reason', 'punish')
def add(request):
if request.method == 'GET':
f = CarRecordForm(initial={'reason': '打警察', 'punish': '牢底坐穿'})
else:
f = CarRecordForm(request.POST)
if f.is_valid():
f.save()
return redirect('/search2')
return render(request, 'add.html', {'f': f})
<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>
<style>
.err {
color: red;
font-size: 14px;
}
</style>
</head>
<body>
<h2>添加违章记录</h2>
<hr>
<p>
{% for hint in hints %}
<div class="err">{{ hint }}</div>
{% endfor %}
</p>
<form action="/add" method="post">
{% for field in f.visible_fields %}
<div>
{{ field.label }}
{{ field }}
{% for error in field.errors %}
<span class="err">{{ error }}</span>
{% endfor %}
</div>
{% endfor %}
{% 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>
<p>{{ last }}</p>
</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
from django.contrib import admin
from demo.models import Teacher, Subject, User
class UserAdmin(admin.ModelAdmin):
list_display = ('no', 'username', 'email', 'counter')
ordering = ('no', )
class SubjectAdmin(admin.ModelAdmin):
list_display = ('no', 'name', 'intro')
ordering = ('no', )
class TeacherAdmin(admin.ModelAdmin):
list_display = ('no', 'name', 'intro', 'motto', 'subject', 'manager')
search_fields = ('name', 'intro')
ordering = ('no', )
admin.site.register(Subject, SubjectAdmin)
admin.site.register(Teacher, TeacherAdmin)
admin.site.register(User, UserAdmin)
from django.apps import AppConfig
class DemoConfig(AppConfig):
name = '投票'
from django import forms
from demo.models import User
class UserForm(forms.ModelForm):
username = forms.CharField(widget=forms.TextInput, min_length=6, max_length=20)
password = forms.CharField(widget=forms.PasswordInput, min_length=8, max_length=20)
email = forms.CharField(widget=forms.EmailInput, max_length=255)
class Meta(object):
model = User
fields = ('username', 'password', 'email')
# 序列化 - 把对象写入数据流 - 串行化 / 归档 / 腌咸菜
# 反序列化 - 从数据流中恢复出对象 - 反串行化 / 解归档
# Python有三个支持序列化的模块
# json - JSON / pickle - 二进制 / shelve
import json
import pickle
class Student(object):
def __init__(self, name, age):
self.name = name
self.age = age
if __name__ == '__main__':
list1 = [10, 'hello', 99.9, 'goodbye']
print(json.dumps(list1))
print(pickle.dumps(list1))
dict1 = {'name': '骆昊', 'age': 38}
print(json.dumps(dict1))
print(pickle.dumps(dict1))
stu = Student('骆昊', 38)
print(pickle.dumps(stu))
# Generated by Django 2.0.6 on 2018-07-04 02:30
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Subject',
fields=[
('no', models.AutoField(db_column='sno', primary_key=True, serialize=False, verbose_name='编号')),
('name', models.CharField(db_column='sname', max_length=50, verbose_name='学科名称')),
('intro', models.CharField(db_column='sintro', max_length=511, verbose_name='学科介绍')),
],
options={
'db_table': 'tb_subject',
},
),
migrations.CreateModel(
name='Teacher',
fields=[
('no', models.AutoField(db_column='tno', primary_key=True, serialize=False, verbose_name='编号')),
('name', models.CharField(db_column='tname', max_length=20, verbose_name='姓名')),
('intro', models.CharField(db_column='tintro', max_length=1023, verbose_name='简介')),
('motto', models.CharField(db_column='tmotto', max_length=255, verbose_name='教学理念')),
('photo', models.CharField(blank=True, db_column='tphoto', max_length=511, null=True)),
('manager', models.BooleanField(db_column='tmanager', default=False, verbose_name='是否主管')),
('subject', models.ForeignKey(db_column='sno', on_delete=django.db.models.deletion.PROTECT, to='demo.Subject', verbose_name='所属学科')),
],
options={
'db_table': 'tb_teacher',
'ordering': ('name',),
},
),
]
# Generated by Django 2.0.6 on 2018-07-04 03:17
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('demo', '0001_initial'),
]
operations = [
migrations.AlterModelOptions(
name='subject',
options={'verbose_name': '学科', 'verbose_name_plural': '学科'},
),
migrations.AlterModelOptions(
name='teacher',
options={'ordering': ('name',), 'verbose_name': '讲师', 'verbose_name_plural': '讲师'},
),
migrations.AddField(
model_name='teacher',
name='bad_count',
field=models.IntegerField(db_column='sbcount', default=0, verbose_name='差评数'),
),
migrations.AddField(
model_name='teacher',
name='good_count',
field=models.IntegerField(db_column='sgcount', default=0, verbose_name='好评数'),
),
migrations.AlterField(
model_name='teacher',
name='photo',
field=models.CharField(blank=True, db_column='tphoto', max_length=511, null=True, verbose_name='照片'),
),
]
# Generated by Django 2.0.6 on 2018-07-04 03:18
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('demo', '0002_auto_20180704_1117'),
]
operations = [
migrations.AlterField(
model_name='teacher',
name='bad_count',
field=models.IntegerField(db_column='tbcount', default=0, verbose_name='差评数'),
),
migrations.AlterField(
model_name='teacher',
name='good_count',
field=models.IntegerField(db_column='tgcount', default=0, verbose_name='好评数'),
),
]
# Generated by Django 2.0.6 on 2018-07-05 02:17
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('demo', '0003_auto_20180704_1118'),
]
operations = [
migrations.CreateModel(
name='User',
fields=[
('no', models.AutoField(db_column='uno', primary_key=True, serialize=False, verbose_name='编号')),
('username', models.CharField(max_length=20, unique=True, verbose_name='用户名')),
('password', models.CharField(max_length=40, verbose_name='口令')),
('email', models.CharField(max_length=255, verbose_name='邮箱')),
],
options={
'verbose_name': '用户',
'verbose_name_plural': '用户',
'db_table': 'tb_user',
},
),
migrations.AlterField(
model_name='teacher',
name='subject',
field=models.ForeignKey(db_column='sno', on_delete=django.db.models.deletion.PROTECT, related_name='+', to='demo.Subject', verbose_name='所属学科'),
),
]
# Generated by Django 2.0.6 on 2018-07-06 06:58
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('demo', '0004_auto_20180705_1017'),
]
operations = [
migrations.AlterModelOptions(
name='teacher',
options={'ordering': ('no',), 'verbose_name': '讲师', 'verbose_name_plural': '讲师'},
),
migrations.AddField(
model_name='user',
name='counter',
field=models.IntegerField(default=3, verbose_name='票数'),
),
]
from hashlib import sha1
from django.db import models
from django.db.models import PROTECT
proto = sha1()
class User(models.Model):
no = models.AutoField(primary_key=True, db_column='uno', verbose_name='编号')
username = models.CharField(max_length=20, unique=True, verbose_name='用户名')
password = models.CharField(max_length=40, verbose_name='口令')
email = models.CharField(max_length=255, verbose_name='邮箱')
counter = models.IntegerField(default=3, verbose_name='票数')
def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
hasher = proto.copy()
hasher.update(self.password.encode('utf-8'))
self.password = hasher.hexdigest()
super().save(force_insert, force_update, using, update_fields)
class Meta(object):
db_table = 'tb_user'
verbose_name = '用户'
verbose_name_plural = '用户'
class Subject(models.Model):
no = models.AutoField(primary_key=True, db_column='sno', verbose_name='编号')
name = models.CharField(max_length=50, db_column='sname', verbose_name='学科名称')
intro = models.CharField(max_length=511, db_column='sintro', verbose_name='学科介绍')
def __str__(self):
return self.name
class Meta(object):
db_table = 'tb_subject'
verbose_name = '学科'
verbose_name_plural = '学科'
class Teacher(models.Model):
no = models.AutoField(primary_key=True, db_column='tno', verbose_name='编号')
name = models.CharField(max_length=20, db_column='tname', verbose_name='姓名')
intro = models.CharField(max_length=1023, db_column='tintro', verbose_name='简介')
motto = models.CharField(max_length=255, db_column='tmotto', verbose_name='教学理念')
photo = models.CharField(max_length=511, db_column='tphoto', verbose_name='照片', null=True, blank=True)
subject = models.ForeignKey(Subject, db_column='sno', on_delete=PROTECT, related_name='+', verbose_name='所属学科')
manager = models.BooleanField(default=False, db_column='tmanager', verbose_name='是否主管')
good_count = models.IntegerField(default=0, db_column='tgcount', verbose_name='好评数')
bad_count = models.IntegerField(default=0, db_column='tbcount', verbose_name='差评数')
@property
def gcount(self):
return f'{self.good_count}' \
if self.good_count <= 999 else '999+'
@property
def bcount(self):
return f'{self.bad_count}' \
if self.bad_count <= 999 else '999+'
class Meta(object):
db_table = 'tb_teacher'
verbose_name = '讲师'
verbose_name_plural = '讲师'
ordering = ('no', )
from django.test import TestCase
# Create your tests here.
import json
from django.http import HttpResponse
from django.shortcuts import render, redirect
from demo.forms import UserForm
from demo.models import Subject, Teacher, User, proto
def login(request):
if request.method.lower() == 'get':
return render(request, 'demo/login.html', {})
else:
username = request.POST['username']
try:
user = User.objects.get(username__exact=username)
password = request.POST['password']
hasher = proto.copy()
hasher.update(password.encode('utf-8'))
if hasher.hexdigest() == user.password:
request.session['user'] = user
return redirect('sub')
except User.DoesNotExist:
pass
return render(request, 'demo/login.html',
{'hint': '用户名或密码错误'})
def register(request):
form = UserForm()
if request.method.lower() == 'get':
return render(request, 'demo/register.html', {'f': form})
else:
ctx = {}
try:
form = UserForm(request.POST)
ctx['f'] = form
if form.is_valid():
form.save(commit=True)
ctx['hint'] = '注册成功请登录!'
return render(request, 'demo/login.html', ctx)
except:
ctx['hint'] = '注册失败, 请重新尝试!'
return render(request, 'demo/register.html', ctx)
def check_username(request):
ctx = {}
if 'username' in request.GET:
username = request.GET['username']
try:
User.objects.get(username__exact=username)
ctx['valid'] = False
except User.DoesNotExist:
ctx['valid'] = True
return HttpResponse(json.dumps(ctx),
content_type='application/json; charset=utf-8')
def show_subjects(request):
if 'user' in request.session and request.session['user']:
ctx = {'subjects_list': Subject.objects.all()}
return render(request, 'demo/subject.html', ctx)
else:
return render(request, 'demo/login.html',
{'hint': '请先登录!'})
def show_teachers(request, no):
if 'user' in request.session and request.session['user']:
teachers = Teacher.objects.filter(subject__no=no)\
.select_related('subject')
ctx = {'teachers_list': teachers}
return render(request, 'demo/teacher.html', ctx)
else:
return render(request, 'demo/login.html',
{'hint': '请先登录!'})
def make_comment(request, no):
ctx = {'code': 200}
if 'user' in request.session and request.session['user']:
user = request.session['user']
if user.counter > 0:
try:
teacher = Teacher.objects.get(pk=no)
if request.path.startswith('/good'):
teacher.good_count += 1
ctx['result'] = f'好评({teacher.gcount})'
else:
teacher.bad_count += 1
ctx['result'] = f'差评({teacher.bcount})'
teacher.save()
user.counter -= 1
User.objects.filter(username__exact=user.username)\
.update(counter=user.counter)
request.session['user'] = user
except Teacher.DoesNotExist:
ctx['code'] = 404
else:
ctx['code'] = 403
ctx['result'] = '票数不足'
else:
ctx['code'] = 302
ctx['result'] = '请先登录'
return HttpResponse(json.dumps(ctx),
content_type='application/json; charset=utf-8')
import pymysql
pymysql.install_as_MySQLdb()
"""
Django settings for hellodjango project.
Generated by 'django-admin startproject' using Django 2.0.6.
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 = 'j*jr(3-it8$lrp&u@e^!f%8!ws*=jx)ga*ln%l6aqftu-uy1=1'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
SESSION_EXPIRE_AT_BROWSER_CLOSE = False
SESSION_COOKIE_AGE = 1800
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'demo',
]
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 = 'hellodjango.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 = 'hellodjango.wsgi.application'
# Database
# https://docs.djangoproject.com/en/2.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'demo',
'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 = 'zh-hans'
TIME_ZONE = 'Asia/Chongqing'
# internationalization
USE_I18N = True
# localization
USE_L10N = True
USE_TZ = True
SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'
# 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/'
# APPEND_SLASH = False
# DEBUG < INFO < WARNING < ERROR < CRITICAL
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console': {
'class': 'logging.StreamHandler',
},
},
'loggers': {
'django': {
'handlers': ['console'],
'level': os.getenv('DJANGO_LOG_LEVEL', 'DEBUG'),
},
},
}
"""hellodjango 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.urls import path
from demo import views
urlpatterns = [
path('', views.login),
path('login/', views.login),
path('register/', views.register),
path('check/', views.check_username),
path('subjects/', views.show_subjects, name='sub'),
path('subjects/<int:no>/', views.show_teachers),
path('good/<int:no>/', views.make_comment),
path('bad/<int:no>/', views.make_comment),
path('admin/', admin.site.urls),
]
"""
WSGI config for hellodjango 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", "hellodjango.settings")
application = get_wsgi_application()
#!/usr/bin/env python
import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "hellodjango.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)
<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>
This diff is collapsed.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户登录</title>
<style>
#login {
width: 320px;
margin: 20px auto;
}
#login form div {
margin: 10px 0;
}
.hint {
color: red;
font-size: 14px;
}
</style>
</head>
<body>
<h1>用户登录</h1>
<hr>
<div id="login">
<p class="hint">{{ hint }}</p>
<form action="/login/" method="post">
{% csrf_token %}
<div>用户名: </div>
<div>
<input type="text" name="username" required>
</div>
<div>密码: </div>
<div>
<input type="password" name="password" required>
</div>
<div>
<input type="submit" value="登录">
</div>
</form>
<a href="/register">注册新用户</a>
</div>
</body>
</html>
\ No newline at end of file
<!doctype html>
{% load staticfiles %}
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户注册</title>
<style>
#reg {
width: 350px;
margin: 20px auto;
}
#reg form div {
margin: 10px 0;
}
.hint {
color: red;
font-size: 14px;
}
</style>
</head>
<body>
<h1>用户注册</h1>
<hr>
<div id="reg">
<p class="hint">{{ hint }}</p>
<form action="/register/" method="post">
{% csrf_token %}
<div>用户名:</div>
<div>
{{ f.username }}
<span id="uhint"></span>
{% if f.errors.username %}
<span class="hint">用户名无效或者已经被注册</span>
{% endif %}
</div>
<div>密码: </div>
<div>
{{ f.password }}
{% if f.errors.password %}
<span class="hint">无效的密码</span>
{% endif %}
</div>
<div>邮箱: </div>
<div>
{{ f.email }}
{% if f.errors.email %}
<span class="hint">无效的邮箱</span>
{% endif %}
</div>
<input type="submit" value="注册">
</form>
<a href="/">返回登录</a>
</div>
<script src="{% static 'js/jquery.min.js' %}"></script>
<script>
$(function() {
$('#id_username').on('blur', function (evt) {
var $input = $(evt.target);
$.ajax({
'url': '/check/',
'type': 'get',
'data': {'username': $input.val()},
'dataType': 'json',
'success': function(json) {
var $img = $('<img>');
if (json.valid) {
$img.attr('src', '/static/images/icon-yes.svg');
} else {
$img.attr('src', '/static/images/icon-no.svg');
}
$('#uhint').empty().append($img);
}
});
});
});
</script>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>学科信息</title>
<style>
body {
width: 960px;
margin: 0 auto;
}
.sub {
margin: 20px 10px;
}
</style>
</head>
<body>
<h1>学科信息</h1>
<hr>
{% for subject in subjects_list %}
<dl class="sub">
<dt><a href="/subjects/{{ subject.no }}">{{ subject.name }}</a></dt>
<dd>{{ subject.intro }}</dd>
</dl>
{% endfor %}
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
{% load staticfiles %}
<html lang="en">
<head>
<meta charset="UTF-8">
<title>讲师信息</title>
<style>
.container {
width: 960px;
margin: 0 auto;
}
.basic {
width: 60%;
float: left;
}
.potrait {
width: 40%;
float: left;
text-align: right;
}
hr {
clear: both;
}
.button {
display: inline-block;
width: 80px;
height: 30px;
background-color: red;
color: white;
font: 16px/30px Arial;
text-decoration: none;
text-align: center;
}
</style>
</head>
<body>
<!-- 页面的显示逻辑 -->
{% for x in teachers_list %}
<div class="container">
<div class="basic">
<h1>{{ x.name }}老师 - {{ x.subject.name }}</h1>
<p><strong>讲师简介</strong></p>
<p>{{ x.intro }}</p>
<p><strong>教学理念</strong></p>
<p>{{ x.motto }}</p>
<a href="/good/{{ x.no }}" class="button">好评({{ x.gcount }})</a>
<a href="/bad/{{ x.no }}" class="button">差评({{ x.bcount }})</a>
</div>
<div class="potrait">
{% if x.photo %}
<img src="{% static x.photo %}">
{% endif %}
</div>
<hr>
</div>
{% endfor %}
<script src="{% static 'js/jquery.min.js' %}"></script>
<script>
$(function() {
$('.basic .button').on('click', function(evt) {
evt.preventDefault();
var $a = $(evt.target);
var url = $a.attr('href');
$.ajax({
'url': url,
'type': 'get',
'data': {},
'dataType': 'json',
'success': function(json) {
if (json.code == 200) {
$a.text(json.result);
} else if (json.code == 403) {
alert(json.result);
}
},
'error': function() {}
});
});
});
</script>
</body>
</html>
\ No newline at end of file
from django.contrib import admin
from hrs.models import Dept, Emp
class DeptAdmin(admin.ModelAdmin):
list_display = ('no', 'name', 'location')
ordering = ('no', )
class EmpAdmin(admin.ModelAdmin):
list_display = ('no', 'name', 'job', 'sal', 'dept')
search_fields = ('name', 'job')
ordering = ('dept', )
admin.site.register(Dept, DeptAdmin)
admin.site.register(Emp, EmpAdmin)
from django.apps import AppConfig
class HrsConfig(AppConfig):
name = 'hrs'
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
#container {
width: 960px;
margin: 0 auto;
}
#container iframe {
opacity: 0.5;
}
</style>
</head>
<body>
<div id="container">
<iframe src="http://www.jd.com" width="960" height="800"></iframe>
</div>
<textarea rows="10" cols="50"></textarea>
</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'),
),
]
# Generated by Django 2.0.7 on 2018-08-15 05:45
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('hrs', '0003_auto_20180524_1646'),
]
operations = [
migrations.RemoveField(
model_name='dept',
name='excellent',
),
migrations.AlterField(
model_name='dept',
name='location',
field=models.CharField(db_column='dloc', max_length=10, verbose_name='部门所在地'),
),
migrations.AlterField(
model_name='dept',
name='name',
field=models.CharField(db_column='dname', max_length=20, verbose_name='部门名称'),
),
migrations.AlterField(
model_name='dept',
name='no',
field=models.IntegerField(db_column='deptno', primary_key=True, serialize=False, verbose_name='部门编号'),
),
migrations.AlterField(
model_name='emp',
name='dept',
field=models.ForeignKey(db_column='dno', on_delete=django.db.models.deletion.PROTECT, to='hrs.Dept'),
),
migrations.AlterField(
model_name='emp',
name='job',
field=models.CharField(db_column='job', max_length=10),
),
migrations.AlterField(
model_name='emp',
name='mgr',
field=models.IntegerField(blank=True, null=True),
),
migrations.AlterField(
model_name='emp',
name='name',
field=models.CharField(db_column='ename', max_length=20),
),
migrations.AlterField(
model_name='emp',
name='no',
field=models.IntegerField(db_column='empno', primary_key=True, serialize=False),
),
migrations.AlterModelTable(
name='dept',
table='TbDept',
),
migrations.AlterModelTable(
name='emp',
table='TbEmp',
),
]
from django.db import models
# ORM - 对象关系映射
# 对象模型 <---> 关系模型
# 实体类 <---> 二维表
# 属性 <---> 列
# 对象 <---> 记录
class Dept(models.Model):
no = models.IntegerField(db_column='deptno', primary_key=True, verbose_name='部门编号')
name = models.CharField(db_column='dname', max_length=20, verbose_name='部门名称')
location = models.CharField(db_column='dloc', max_length=10, verbose_name='部门所在地')
# excellent = models.BooleanField(default=0, verbose_name='是否优秀')
def __str__(self):
return self.name
class Meta:
db_table = 'TbDept'
class Emp(models.Model):
no = models.IntegerField(db_column='empno', primary_key=True)
name = models.CharField(db_column='ename', max_length=20)
job = models.CharField(db_column='job', max_length=10)
# 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, db_column='dno', on_delete=models.PROTECT)
class Meta:
db_table = 'TbEmp'
from django.test import TestCase
# Create your tests here.
from django.urls import path
from hrs import views
urlpatterns = [
path('depts', views.depts, name='depts'),
# 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.db.models import ObjectDoesNotExist
from json import dumps
from hrs.models import Dept, Emp
def index(request):
ctx = {
'greeting': '你好,世界!'
}
return render(request, 'index.html', context=ctx)
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='0'):
# no = request.GET['no']
# dept = Dept.objects.get(no=no)
# ForeignKey(Dept, on_delete=models.PROTECT, related_name='emps')
# dept.emps.all()
# emps_list = dept.emp_set.all()
# all() / filter() ==> QuerySet
# QuerySet使用了惰性查询 - 如果不是非得取到数据那么不会发出SQL语句
# 这样做是为了节省服务器内存的开销 - 延迟加载 - 节省空间势必浪费时间
emps_list = list(Emp.objects.filter(dept__no=no).select_related('dept'))
ctx = {'emp_list': emps_list, 'dept_name': emps_list[0].dept.name} \
if len(emps_list) > 0 else {}
return render(request, 'emp.html', context=ctx)
def depts(request):
ctx = {'dept_list': Dept.objects.all()}
return render(request, 'dept.html', context=ctx)
#!/usr/bin/env python
import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "oa.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)
import pymysql
pymysql.install_as_MySQLdb()
"""
Django settings for oa 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 = 'c^dt134g38w^r4+0f$dpoe)1d5)q1kn+2%g--#!*+xvvn&93=_'
# 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',
'hrs',
]
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 = 'oa.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 = 'oa.wsgi.application'
# Database
# https://docs.djangoproject.com/en/2.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'HRS',
'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 = 'zh-hans'
TIME_ZONE = 'Asia/Chongqing'
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/'
# 配置将日志输出到控制台 日志级别为DEBUG(最详细的日志)
# DEBUG < INFO < WARNING < ERROR < CRITICAL
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console': {
'class': 'logging.StreamHandler',
},
},
'loggers': {
'django': {
'handlers': ['console'],
'level': os.getenv('DJANGO_LOG_LEVEL', 'DEBUG'),
},
},
}
"""oa 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.urls import path, include
from hrs import views
urlpatterns = [
path('', views.index),
path('admin/', admin.site.urls),
path('hrs/', include('hrs.urls')),
]
"""
WSGI config for oa 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", "oa.settings")
application = get_wsgi_application()
asn1crypto==0.24.0
cffi==1.11.5
cryptography==2.3
Django>=2.1.6
idna==2.7
pycparser==2.18
PyMySQL==0.9.2
pytz==2018.5
six==1.11.0
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This diff is collapsed.
<!DOCTYPE html>
{% load static %}
<html lang="en">
<head>
<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">
<div class="row clearfix">
<div class="col-md-12 column">
<h3>部门信息</h3>
<hr>
</div>
</div>
<div class="row clearfix">
<div class="col-md-8 column">
<table id="dept" class="table table-striped table-hover">
<thead>
<tr>
<th>部门编号</th>
<th>部门名称</th>
<th>部门所在地</th>
<th>是否优秀</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for dept in dept_list %}
<tr>
<td>{{ dept.no }}</td>
<td>
<!-- 写代码时要尽量避免使用硬编码(hard code) -->
<a href="{% url 'empsindept' dept.no %}">{{ dept.name }}</a>
</td>
<td>{{ dept.location }}</td>
<td>
{% if dept.excellent %}
<span style="color: green;"></span>
{% else %}
<span style="color: red;">×</span>
{% endif %}
</td>
<td>
<a id="{{ dept.no }}" href="javascript:void(0);" class="btn btn-xs btn-warning">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="col-md-4 column">
</div>
</div>
</div>
<script src="{% static 'js/jquery.min.js' %}"></script>
<script src="{% static 'js/bootstrap.min.js' %}"></script>
<script>
$(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>
</html>
\ No newline at end of file
<!DOCTYPE html>
{% load static %}
<html lang="en">
<head>
<meta charset="UTF-8">
<title>员工</title>
<link href="{% static 'css/bootstrap.min.css' %}" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row clearfix">
<div class="col-md-12 column">
<h3>{{ dept_name }}员工信息</h3>
<hr>
</div>
</div>
<div class="row clearfix">
<div class="col-md-8 column">
{% if emp_list %}
<table id="dept" class="table table-striped table-hover">
<thead>
<tr>
<th>编号</th>
<th>姓名</th>
<th>职位</th>
<th>月薪</th>
<th>部门名称</th>
</tr>
</thead>
<tbody>
{% for emp in emp_list %}
<tr>
<td>{{ emp.no }}</td>
<td>{{ emp.name }}</td>
<td>{{ emp.job }}</td>
<td>{{ emp.sal }}</td>
<td>{{ dept_name }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<h2>此部门暂时没有员工!</h2>
{% endif %}
</div>
<div class="col-md-4 column">
</div>
</div>
<a href="{% url 'depts' %}">返回部门列表</a>
</div>
<script src="{% static 'js/jquery.min.js' %}"></script>
<script src="{% static 'js/bootstrap.min.js' %}"></script>
<script>
$(function() {
$('#dept tbody tr:even').addClass('info');
$('#dept tbody tr:odd').addClass('warning');
});
</script>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
{% load staticfiles %}
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<h1>{{ greeting }}</h1>
<hr>
<img src="{% static 'images/mm.jpg' %}" alt="">
</body>
</html>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment