employee models
import os
import django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'salary.settings')
django.setup(set_prefix=False)
from employee.models import Employee, Salary, Department, Dept_emp
from students.models import Student, Score
from django.db.models import Q, Avg, Sum, Max, Min, Count
emps = Employee.objects.all()
smps = Salary.objects
dmps = Department.objects
demps = Dept_emp.objects
# --- 多对多查询
# 查询10010员工的所在的部门编号及员工信息
# es = emps.get(pk=10010)
# ed = es.dept_emp_set.all() # 记得加all(),不然会返回None
# print(es)
# print(ed)
# for i in ed:
# print(type(i), i)
# e = i.emp_no
# print(type(e), e)
# d = i.dept_no
# print(type(d), d, d.dept_no, d.dept_name)
# --- 一对多查询
# print(smps.all())
# print(smps.filter(pk__gt=30)) # 直接用Salary.objects即可管理
#
# print(*Employee.__dict__.items(), sep='\n')
# print('-'*30)
# print(*Salary.__dict__.items(), sep='\n')
# 查询1004号员工的所有工资(建议从"一"端查,只查询一次)
# print(emps.get(pk=10004).salary_set.all()) # 记得加all()
# 工资大于55000的所有员工的姓名
# print(smps.filter(salary__gt=55000).values('emp_no').distinct())
# 查询1004号员工的所有工资及姓名(建议从"一"端查,只查询一次)
# print(emps.get(pk=10004).salary_set.all()) # 记得加all()
# print(emps.get(pk=10004).name)
# 查询工资大于55000的所有员工姓名(emp_no仅表示关系,salary_set,emp_no才是2个表真正用的属性)
# nos = smps.filter(salary__gt=55000)
# names = set()
# for i in nos:
# names.add(i.emp_no.name)
# print(names)
# 查询10004员工所有工资及姓名
# slist = list(smps.filter(emp_no=10004).filter(salary__gt=55000))
# for s in slist:
# print(s.emp_no.name, s.emp_no_id, s.salary) # s.emp_no 这里的emp_no表示【关系】
# 员工大于55000的所有员工的姓名
#
# sql = """
# SELECT DISTINCT e.emp_no, e.first_name, e.last_name
# FROM employees e JOIN salaries s
# ON e.emp_no=s.emp_no
# WHERE s.salary > 55000
# """
# # print(emps.raw(sql)) #惰性的set
# print(list(emps.raw(sql)))
# --- 缓存验证
# print(emps)
# print(*emps, sep='\n')
# print(emps[0].gender, emps[0].get_gender_display())
# print(type(emps))
# print(1, emps)
# print(2, emps)
# print(3, emps[0])
# print(4, emps[0])
# print(emps._result_cache)
# # 上面共查询了4次数据库,emps._result_cache为None,说明emps是惰性的
# print(type(emps)) # QuerySet查询集
# print(list(emps)) # print(*emps) 先遍历一遍,缓存住
# print(1, emps)
# print(2, emps)
# print(3, emps[0])
# print(4, emps[:])
# print(emps._result_cache) # 结果集列表
# # 上面list(emps)进行了缓存,所以下面4个就不进行查询了,直接利用了缓存,综合查询了1次
# # --- 切片和步长
# print(emps[10:15])
# print(emps[20:30])
# print(emps[0:20:5])
# print(emps[::5])
# # --- 结果集查询
# print(emps.values())
# print(emps.filter(pk=10010).values())
# print(emps.exclude(emp_no=10001))
# print(emps.exclude(emp_no=10002).order_by('emp_no'))
# print(emps.exclude(emp_no=10002).order_by('-pk'))
# print(emps.exclude(emp_no=10002).order_by('-pk').values())
# # values返回的集合里的元素是字典
# # --- 单值查询
# print(emps.filter(pk=10010).get())
# print(emps.get(pk=10001))
# #print(emps.exclude(pk=10010).get()) # get严格一个
# print(emps.first()) # limit 1
# print(emps.exclude(pk=10010).last()) # desc, limit 1
# print(emps.filter(pk=10010, gender=1).first()) # AND,找不到返回None
# print(emps.count())
# print(emps.exclude(pk=10010).count())
# # --- LOOKUP表达式
# print(emps.filter(emp_no__exact=10010)) # 就是等于,所以很少用exact
# print(emps.filter(pk__in=[10010, 10009]))
# print(emps.filter(last_name__startswith='P'))
# print(emps.exclude(pk__gt=10003))
# # --- Q对象
# print(emps.filter(Q(pk__lt=10006))) # 不如直接写filter(pk__lt=10006)
# # 下面几句一样
# print(emps.filter(pk__gt=10003).filter(pk__lt=10006)) # 与
# print(emps.filter(pk__gt=10003, pk__lt=10006)) # 与
# print(emps.filter(Q(pk__gt=10003), Q(pk__lt=10006)))
# print(emps.filter(Q(pk__gt=10003) & Q(pk__lt=10006))) # 与
# print(emps.filter(pk__gt=10003) & emps.filter(pk__lt=10006))
# # 下面几句等价
# print(emps.filter(pk__in=[10003, 10006])) # in
# print(emps.filter(Q(pk=10003) | Q(pk=10006))) # 或
# print(emps.filter(pk=10003) | emps.filter(pk=10006))
#
# print(emps.filter(~Q(pk__gt=10003))) # 非
# # 可使用&|和Q对象来构造复杂的逻辑表达式,可以使用一个或多个Q对象。
# # 如果混用关键字参数和Q对象,那么Q对象必须位于关键字参数的前面。
# --- 聚合分组
# # aggregate() 返回字典,方便使用
# print(emps.filter(pk__gt=10010).count()) # 单值
# print(emps.filter(pk__gt=10010).aggregate(Count('pk'), Max('pk'))) # 字典
# print(emps.filter(pk__lte=10010).aggregate(Avg('pk')))
# print(emps.aggregate(Max('pk'), min=Min('pk'))) # 别名
# # annotate()方法用来分组聚合,返回查询集。
# print(emps.filter(pk__gt=10010).aggregate(Count('pk'))) # 字典
# s = emps.filter(pk__gt=10010).annotate(Count('pk')) # 返回查询集,没指定分组字段,
# # print(s)
# # 使用主键分组
# for x in s:
# print(x)
# print(x.__dict__) # 里面多了一个属性pk__count
# # values()方法,放在annotate前就是指定分组字段,之后就是取结果中的字段。
# s = emps.filter(pk__gt=10010).values('gender').annotate(Count('pk')) # 查询集
# print(s)
# for x in s:
# print(x) # 字典
# s = emps.filter(pk__gt=10010).values('gender').annotate(c=Count('pk')).order_by('-c') # 查询集
# print(s)
# for x in s:
# print(x) # 字典
# s = emps.filter(pk__gt=10010).values('gender').annotate(Avg('pk'), c=Count('pk')).order_by('-c').values('pk__avg', 'c') # 查询集,但后面的values过滤了每个对象字典的key
# print(s)
# for x in s:
# print(x) # 字典
# --- 练习题(记得用test2数据库)
# # # 导入数据
#
# stu_list = [('王一涵',10),('张青阳',12),('韩名博',12),('王梓',13),('骆铭峰',11),('赢乘风',11),('林烽',10),('吴博文',12),('马小文',12)]
# sco_list = [(1,'语文',90,'王一涵'),(2,'数学',80,'王一涵'),(3,'英语',75,'王一涵'),(4,'语文',95,'张青阳'),(5,'数学',90,'张青阳'),(6,'英语',98,'张青阳'),(7,'语文',80,'韩名博'),(8,'数学',89,'韩名博'),(9,'英语',70,'韩名博'),(10,'语文',60,'王梓'),(11,'数学',75,'王梓'),(12,'英语',65,'王梓'),(13,'语文',81,'骆铭峰'),(14,'数学',82,'骆铭峰'),(15,'英语',55,'骆铭峰'),(16,'语文',78,'赢乘风'),(17,'数学',89,'赢乘风'),(18,'英语',65,'赢乘风'),(19,'语文',89,'林烽'),(20,'数学',60,'林烽'),(21,'英语',49,'林烽'),(22,'语文',89,'吴博文'),(23,'数学',92,'吴博文'),(24,'英语',79,'吴博文'),(25,'语文',50,'马小文'),(26,'数学',60,'马小文'),(27,'英语',62,'马小文')]
#
# for k,v in stu_list:
# Student(k,v).save()
#
# for s1,s2,s3,s4 in sco_list:
# Score(s1,s2,s3,s4).save()
#
#
# # 查询
#
# stu = Student.objects.all()
# sco = Score.objects.all()
#
# # 总成绩大于250分的学生信息
# print(sco.values('name').annotate(Sum('score')).filter(score__sum__gt=250))
# # 语文成绩在80-90分之间的学生信息
# print(sco.filter(exam_subjects='语文').filter(score__gt=80,score__lt=90))
# # 有一门科目低于60分的学生信息
# print(sco.filter(score__lt=60).values('name').annotate())
# # 平均分70以上的学生信息
# print(sco.values('name').annotate(Avg('score')).filter(score__avg__gt=70))
# # 三门成绩都大于90分的学生姓名
# print(sco.filter(score__gte=90).values('name').annotate(Count('score')).filter(score__count=3))
students models
from django.db import models
# Create your models here.
class Student(models.Model):
class Mate:
db_table = 'students'
# id = models.AutoField(primary_key=True)
name = models.CharField(primary_key=True, max_length=30, verbose_name='姓名')
age = models.PositiveSmallIntegerField(verbose_name='年龄')
def __repr__(self):
return '{} {}'.format(self.name, self.age)
__str__ = __repr__
class Score(models.Model):
class Mate:
db_table = 'scroes'
id = models.AutoField(primary_key=True)
exam_subjects = models.CharField(max_length=40, verbose_name='科目')
score = models.PositiveSmallIntegerField(verbose_name='分数')
name = models.ForeignKey(Student, db_column='name', on_delete=models.CASCADE)
# to_field = name (默认用的Studentde主键)
# name表示关系,db_column='name'的name表示数据库显示的名称(数据库用的名称),ORM真正与数据的name对应的却是name_id
def __repr__(self):
return '{} {} {}'.format(self.exam_subjects, self.score, self.name_id)
__str__ = __repr__
test.py
import os
import django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'salary.settings')
django.setup(set_prefix=False)
from employee.models import Employee, Salary, Department, Dept_emp
from students.models import Student, Score
from django.db.models import Q, Avg, Sum, Max, Min, Count
emps = Employee.objects.all()
smps = Salary.objects
dmps = Department.objects
demps = Dept_emp.objects
# --- 多对多查询
# 查询10010员工的所在的部门编号及员工信息
# es = emps.get(pk=10010)
# ed = es.dept_emp_set.all() # 记得加all(),不然会返回None
# print(es)
# print(ed)
# for i in ed:
# print(type(i), i)
# e = i.emp_no
# print(type(e), e)
# d = i.dept_no
# print(type(d), d, d.dept_no, d.dept_name)
# --- 一对多查询
# print(smps.all())
# print(smps.filter(pk__gt=30)) # 直接用Salary.objects即可管理
#
# print(*Employee.__dict__.items(), sep='\n')
# print('-'*30)
# print(*Salary.__dict__.items(), sep='\n')
# 查询1004号员工的所有工资(建议从"一"端查,只查询一次)
# print(emps.get(pk=10004).salary_set.all()) # 记得加all()
# 工资大于55000的所有员工的姓名
# print(smps.filter(salary__gt=55000).values('emp_no').distinct())
# 查询1004号员工的所有工资及姓名(建议从"一"端查,只查询一次)
# print(emps.get(pk=10004).salary_set.all()) # 记得加all()
# print(emps.get(pk=10004).name)
# 查询工资大于55000的所有员工姓名(emp_no仅表示关系,salary_set,emp_no才是2个表真正用的属性)
# nos = smps.filter(salary__gt=55000)
# names = set()
# for i in nos:
# names.add(i.emp_no.name)
# print(names)
# 查询10004员工所有工资及姓名
# slist = list(smps.filter(emp_no=10004).filter(salary__gt=55000))
# for s in slist:
# print(s.emp_no.name, s.emp_no_id, s.salary) # s.emp_no 这里的emp_no表示【关系】
# 员工大于55000的所有员工的姓名
#
# sql = """
# SELECT DISTINCT e.emp_no, e.first_name, e.last_name
# FROM employees e JOIN salaries s
# ON e.emp_no=s.emp_no
# WHERE s.salary > 55000
# """
# # print(emps.raw(sql)) #惰性的set
# print(list(emps.raw(sql)))
# --- 缓存验证
# print(emps)
# print(*emps, sep='\n')
# print(emps[0].gender, emps[0].get_gender_display())
# print(type(emps))
# print(1, emps)
# print(2, emps)
# print(3, emps[0])
# print(4, emps[0])
# print(emps._result_cache)
# # 上面共查询了4次数据库,emps._result_cache为None,说明emps是惰性的
# print(type(emps)) # QuerySet查询集
# print(list(emps)) # print(*emps) 先遍历一遍,缓存住
# print(1, emps)
# print(2, emps)
# print(3, emps[0])
# print(4, emps[:])
# print(emps._result_cache) # 结果集列表
# # 上面list(emps)进行了缓存,所以下面4个就不进行查询了,直接利用了缓存,综合查询了1次
# # --- 切片和步长
# print(emps[10:15])
# print(emps[20:30])
# print(emps[0:20:5])
# print(emps[::5])
# # --- 结果集查询
# print(emps.values())
# print(emps.filter(pk=10010).values())
# print(emps.exclude(emp_no=10001))
# print(emps.exclude(emp_no=10002).order_by('emp_no'))
# print(emps.exclude(emp_no=10002).order_by('-pk'))
# print(emps.exclude(emp_no=10002).order_by('-pk').values())
# # values返回的集合里的元素是字典
# # --- 单值查询
# print(emps.filter(pk=10010).get())
# print(emps.get(pk=10001))
# #print(emps.exclude(pk=10010).get()) # get严格一个
# print(emps.first()) # limit 1
# print(emps.exclude(pk=10010).last()) # desc, limit 1
# print(emps.filter(pk=10010, gender=1).first()) # AND,找不到返回None
# print(emps.count())
# print(emps.exclude(pk=10010).count())
# # --- LOOKUP表达式
# print(emps.filter(emp_no__exact=10010)) # 就是等于,所以很少用exact
# print(emps.filter(pk__in=[10010, 10009]))
# print(emps.filter(last_name__startswith='P'))
# print(emps.exclude(pk__gt=10003))
# # --- Q对象
# print(emps.filter(Q(pk__lt=10006))) # 不如直接写filter(pk__lt=10006)
# # 下面几句一样
# print(emps.filter(pk__gt=10003).filter(pk__lt=10006)) # 与
# print(emps.filter(pk__gt=10003, pk__lt=10006)) # 与
# print(emps.filter(Q(pk__gt=10003), Q(pk__lt=10006)))
# print(emps.filter(Q(pk__gt=10003) & Q(pk__lt=10006))) # 与
# print(emps.filter(pk__gt=10003) & emps.filter(pk__lt=10006))
# # 下面几句等价
# print(emps.filter(pk__in=[10003, 10006])) # in
# print(emps.filter(Q(pk=10003) | Q(pk=10006))) # 或
# print(emps.filter(pk=10003) | emps.filter(pk=10006))
#
# print(emps.filter(~Q(pk__gt=10003))) # 非
# # 可使用&|和Q对象来构造复杂的逻辑表达式,可以使用一个或多个Q对象。
# # 如果混用关键字参数和Q对象,那么Q对象必须位于关键字参数的前面。
# --- 聚合分组
# # aggregate() 返回字典,方便使用
# print(emps.filter(pk__gt=10010).count()) # 单值
# print(emps.filter(pk__gt=10010).aggregate(Count('pk'), Max('pk'))) # 字典
# print(emps.filter(pk__lte=10010).aggregate(Avg('pk')))
# print(emps.aggregate(Max('pk'), min=Min('pk'))) # 别名
# # annotate()方法用来分组聚合,返回查询集。
# print(emps.filter(pk__gt=10010).aggregate(Count('pk'))) # 字典
# s = emps.filter(pk__gt=10010).annotate(Count('pk')) # 返回查询集,没指定分组字段,
# # print(s)
# # 使用主键分组
# for x in s:
# print(x)
# print(x.__dict__) # 里面多了一个属性pk__count
# # values()方法,放在annotate前就是指定分组字段,之后就是取结果中的字段。
# s = emps.filter(pk__gt=10010).values('gender').annotate(Count('pk')) # 查询集
# print(s)
# for x in s:
# print(x) # 字典
# s = emps.filter(pk__gt=10010).values('gender').annotate(c=Count('pk')).order_by('-c') # 查询集
# print(s)
# for x in s:
# print(x) # 字典
# s = emps.filter(pk__gt=10010).values('gender').annotate(Avg('pk'), c=Count('pk')).order_by('-c').values('pk__avg', 'c') # 查询集,但后面的values过滤了每个对象字典的key
# print(s)
# for x in s:
# print(x) # 字典
# --- 练习题(记得用test2数据库)
# # # 导入数据
#
# stu_list = [('王一涵',10),('张青阳',12),('韩名博',12),('王梓',13),('骆铭峰',11),('赢乘风',11),('林烽',10),('吴博文',12),('马小文',12)]
# sco_list = [(1,'语文',90,'王一涵'),(2,'数学',80,'王一涵'),(3,'英语',75,'王一涵'),(4,'语文',95,'张青阳'),(5,'数学',90,'张青阳'),(6,'英语',98,'张青阳'),(7,'语文',80,'韩名博'),(8,'数学',89,'韩名博'),(9,'英语',70,'韩名博'),(10,'语文',60,'王梓'),(11,'数学',75,'王梓'),(12,'英语',65,'王梓'),(13,'语文',81,'骆铭峰'),(14,'数学',82,'骆铭峰'),(15,'英语',55,'骆铭峰'),(16,'语文',78,'赢乘风'),(17,'数学',89,'赢乘风'),(18,'英语',65,'赢乘风'),(19,'语文',89,'林烽'),(20,'数学',60,'林烽'),(21,'英语',49,'林烽'),(22,'语文',89,'吴博文'),(23,'数学',92,'吴博文'),(24,'英语',79,'吴博文'),(25,'语文',50,'马小文'),(26,'数学',60,'马小文'),(27,'英语',62,'马小文')]
#
# for k,v in stu_list:
# Student(k,v).save()
#
# for s1,s2,s3,s4 in sco_list:
# Score(s1,s2,s3,s4).save()
#
#
# # 查询
#
# stu = Student.objects.all()
# sco = Score.objects.all()
#
# # 总成绩大于250分的学生信息
# print(sco.values('name').annotate(Sum('score')).filter(score__sum__gt=250))
# # 语文成绩在80-90分之间的学生信息
# print(sco.filter(exam_subjects='语文').filter(score__gt=80,score__lt=90))
# # 有一门科目低于60分的学生信息
# print(sco.filter(score__lt=60).values('name').annotate())
# # 平均分70以上的学生信息
# print(sco.values('name').annotate(Avg('score')).filter(score__avg__gt=70))
# # 三门成绩都大于90分的学生姓名
# print(sco.filter(score__gte=90).values('name').annotate(Count('score')).filter(score__count=3))
settings.py
"""
Django settings for salary project.
Generated by 'django-admin startproject' using Django 3.2.6.
For more information on this file, see
https://docs.djangoproject.com/en/3.2/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.2/ref/settings/
"""
from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-(uouz1h2%5ey)2+n6o8efxd+p+h!@m&we+1%6erp6ng79j9p#2'
# 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',
'employee',
'students',
]
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 = 'salary.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'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 = 'salary.wsgi.application'
# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'OPTIONS': {'charset': 'utf8'},
'NAME': 'test',
'USER': 'soymilk',
'PASSWORD': '123456',
'HOST': '172.16.241.2',
'PORT': '3306',
}
}
# Password validation
# https://docs.djangoproject.com/en/3.2/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/3.2/topics/i18n/
LANGUAGE_CODE = 'zh-Hans' # 'en-us'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/
STATIC_URL = '/static/'
# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console': {
'class': 'logging.StreamHandler',
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'level': 'DEBUG',
},
},
}