[后端开发] Django学习笔记

django起步

安装pycharm profession

链接: https://pan.baidu.com/s/15JuRTj6i6deFVl0AyyNzEg 提取码: 4id3

破解方案:https://zhuanlan.zhihu.com/p/678016389

创建虚拟环境

第1步 :安装virtualenv和virtualenvwrapper

pip3 install -i https://mirrors.aliyun.com/pypi/simple virtualenv
pip3 install -i https://mirrors.aliyun.com/pypi/simple virtualenvwrapper

第2步,创建管理虚拟环境的根目录

cd  /自定义虚拟环境文件夹
mkdir pyVirtualEnv
virtualenv   虚拟环境名
source 虚拟环境名/bin/activate

//安装
pip3 install django 
//查看django版本
python -m django --version 
//卸载
pip3 uninstall django 
//创建项目名
django-admin startproject 项目名(eg:demo)
//启动服务
python manage.py runserver IP
//创建模块
python manage.py startapp  模块名(eg:hello)

pycharm 链接数据库

image.png

报错:No module named 'distutils'

安装setuptools
pip install setuptools

Django ORM模型数据类型

安装依赖

pip install says "Can not find valid pkg-config name" since mysqliclient 2.2

pip3 install mysqlclient==2.0

ImportError: dlopen(/Users/主机名/Doc/PyProject/apiServer/.venv/lib/python3.12/site-packages/MySQLdb/_mysql.cpython-312-darwin.so, 0x0002): Library not loaded: @rpath/libmysqlclient.22.dylib
Referenced from: <CC7E60FB-42D3-3AD1-8BB4-1F706F02E65E> /Users/主机名/Doc/PyProject/apiServer/.venv/lib/python3.12/site-packages/MySQLdb/_mysql.cpython-312-darwin.so

sudo install_name_tool -change @rpath/libmysqlclient.22.dylib /usr/local/mysql/lib/libmysqlclient.22.dylib /Users/主机名/Doc/PyProject/apiServer/.venv/lib/python3.12/site-packages/MySQLdb/_mysql.cpython-312-darwin.so
  • 数据库常见数据类型
    • char 固定长度字符
    • varchar 可变长度字符
    • text 长文本
    • float /decimal 浮点数
    • int/tinyint 整数
    • date/time/datetime 日期时间
  • Django ORM数据模型数据类型
    • CharField(字符串),TextField (文本)、FileField、 ImageField 、EmailField 、URLField、FilePathField
    • IntegerField(整数) 、BooleanField(0,1布尔值)、PositiveIntegerField 正整数
    • DateField 日期、TimeField时间、DateTimeField 日期时间
配置步骤
  • 将创建模块的模块键入到INSTALLED_APPS 中
python manage.py startapp accounts 
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
+    'hello',
+   'accounts'
]
  • 编写模型代码
  • 模型代码转换成sql语句
python manage.py check 
python manage.py makemigrations
python manage.py migrate

模型元数据

模型内部的Meta类,是关于该模型的一些描述性字段

  • db_table 数据库表名称
  • ordering 默认排序规则 ['-create_at ']倒序,
  • verbose_name 标的描述
  • abstract 抽象类
  • proxy 代理模型,是父模型的功能扩充
class commonModel(models.Model):
   create_at = models.DateTimeField("注册时间",auto_now_add=True)
   update_at = models.DateTimeField("跟新时间",auto_now=True) 

 class Meta:
     abstract=True
class UserModel(commonModel):
       .....

class ManagerUser(UserModel):

   def getXXX(self):

   class Meta:
     proxy =True

关联关系

  • 一对一 OneToOneField(to,on_delete,parent_link=False,**options)
class UserModel(models.Model):
        name = models.CharField('姓名',max_length=64)

class UserPorfileModel(models.Model):
    # user = new UserModel()
    # user.profile就可以拿到用户的信息
      user = models.OneToOneField('UserModel',on_delete=models.CASCADE,related_name='profile',db_column='new_column_name')

  • 一对多 ForeignKey(to,on_delete)
class Question(models.Model):
        title= models.CharField('问题描述',max_length=64)

class Answer(models.Model):
        question = models.ForeignKey('Question',on_delete=models.CASCADE,related_name='answers',verbose_name='关联的问题')
        content = models.TextField("描述",default='')
  • 多对多 ManyToManyField(to,**options)
class UserModel(models.Model):
      collected_question =  models.ManyToManyField('Question',...)

to 关联的模型(模型类,模型字符串,self)
on_delete 删除选项

  • models.CASCADE:关联删除
  • models.PROTECT:受保护的
  • SET_NULL:设置为null,需要字段模型中null=True
  • SET_DEFAULT 设置为默认值,模型字段需要设置default值
  • SET()传入设置值
  • DO_NOTHING 什么都不做
  • related_name 通过关联对象[related_name字段]可以拿到
  • db_column 修改默认(XXX_id)的反向引用的表字段名称

ORM新增数据

  • save() 创建或更新
user_obj1= UserModel(username='张三',password='****')
user_obj1.save()
  • create()
user_ob2j= UserModel.objects.create(username='张三',password='****')
  • bulk_create()
bulk_user_list = [user_obj1,user_obj2]
UserModel.objects.bulk_create(bulk_user_list)

关联数据的新增

class UserLoginHstory(models.Model):
  user = models.ForeignKey('UserModel',related_name='relate_history_list',on_delete=models.CASCADE,verbose_name='关联的用户')
  username = models.CharField('用户名',max_length=128)
  ip = models.CharField('ip地址',max_length=64,default='')
....
UserModel.objects.create(user_obj1,username='李四',ip='127.0.0.1')


ORM查询

  • get(**kwargs) 按照条件单条查询
UserModel.objects.get(id=1,username='lishi')
  • latest(fields) ,earliest(fields) 返回昨早最晚的一条记录
UserModel.objects.earliest('created_at')
  • first() ,last()返回第一条或最后一条
  • all() 返回所有
  • get_or_create 没查到就新建

ORM修改数据

  • save()
user_obj1= UserModel(username='张三',password='****')
user_obj1.username = '李四'
user_obj1.save()
  • update() 不能修改外键关联的对象
user_ob2j= UserModel.objects.all(')
user_obj1.update(status=1)
  • bulk_update(objs,fields,batch_size=None)
    • objs需要修改的记录列表
    • fields指定需要修改的字段
    • batch_size每次提交多条数据修改

ORM删除数据

  • 查询结果集.delete()

ORM结果集查询条件

结果集查询常用方法:
  • all()
  • filter()
  • exists()是否有记录
  • exclude('id=1')
  • order_by('+-字段名称')
  • count() 查询数量
  • using('default')用配置的指定数据库查询,默认default,见settings.py
  • QuerySet.query() 查看sql语句
  • 相等/等于
from account.models import User
user_list = User.objects.all().filter(id=6)
user_list = User.objects.all().filter(id__exact=6)
#等于sql 的 LIKE  :像**的值
user_list = User.objects.all().filter(username__iexact='ang')  
  • 布尔条件
    • gt 大于
    • gte大于等于
    • lt小于
    • lte 小于等于
    • isnull是否空
user_list = User.objects.all().filter(nickname__isnull=True)
  • 字符串相关
user_list = User.objects.all().filter(nickname__contains='zhang')#包含
user_list = User.objects.all().filter(nickname__icontains='zhang')#不包含
user_list = User.objects.all().filter(status__in=[1,3])
user_list = User.objects.all().filter(username__startswith='ahang')#区分大小写
user_list = User.objects.all().filter(username__istartswith='Ahang')#不区分大小写
user_list = User.objects.all().filter(username__endswith='ahang')#区分大小写
user_list = User.objects.all().filter(username__iendswith='Ahang')#不区分大小写
  • 日期时间查询
    • year
    • month
    • day
    • hour/minute/second
    • week/week_day

从年到后面都是一样的,只是date可以传date对象过去

from datetime import datetime

d = datetime(2022,5,25).date()
user_list = User.objects.all().filter(updated_at__date=d )
user_list = User.objects.all().filter(updated_at__day=25 )

外键关联

from account.models import UserProfile
#user是UserProfile模型中的一个字段和User模型是一对一关系
UserProfile.objects.all().filter(user__username__contains='管理员').count()#查个数

多条件查询

user_list = User.objects.all().filter(username__contains='管理员' ).filter(status_exact='1')
user_list = User.objects.all().filter(username__contains='管理员' ,status='1')
query1 = User.objects.all().filter(username__contains='管理员' )
query2 = User.objects.all().filter(status_exact='1')
user_list  = query1 & query2

使用Q函数实现多条件查询

from django.db.models import Q 

query1 = Q(username__contains='管理员' ,status='1')
query2 = Q(username__contains='管理员') & Q(status='1')
user_list  =  User.objects.all().filter(query1)

query3= Q(username__contains='管理员') | Q(status='1')
user_list  =  User.objects.all().filter(query3 )

模型查询优化

UserProfile.objects.all().select_related('user')#将外键关联的对象合并到主查询里面

模型分页处理

from django.core.paginator import Paginator

all_data=list(range(50))
page_size=10
page=Paginator(all_data,page_size)
print(page.num_pages)#获取总共分了多少页
print(page.count)#总共多少条数据

page_obj=page.get_page(1)#获取第一页数据
print('page_obj',page_obj.number)#获取当前所在分页
print(page_obj.has_next())#获取有没有下一页
print(page_obj.paginator.num_pages)#用当前页面的对象,去获取总共多少页
print(page_obj.paginator.count)#用当前页面的对象,去获取总共有多少条数据
print(page_obj.has_previous())#获取有没有上一页
print(page_obj.has_other_pages())#获取有没有其他页
print(page.get_page(2).object_list)#object_list返回的数据是一个list

模型聚合统计

  • Max/Min
  • Sum
  • Avg
  • Count

aggregate 重整个查询结果集中生成统计数据,返回的是一个结果

grade_list = Grade.objects.all().filter(student_name='张三')
total = grade_list .aggregate(Sum("score'))

annotate为查询结果集中每一样生成统计数据,返回的是列表结果

#models.py
from django.db import models


class Student(models.Model):
    """ 学生表 """
    name = models.CharField('学生的姓名', max_length=32)
    age = models.SmallIntegerField('学生年龄', default=0)

    class Meta:
        db_table = 'grade_student'


class Grade(models.Model):
    """ 学生成绩 """
    student = models.ForeignKey(Student,on_delete=models.CASCADE, null=True,
                                related_name='stu_grade')
    student_name = models.CharField('学生的姓名', max_length=32)
    subject_name = models.CharField('科目', max_length=32)
    score = models.FloatField('分数', default=0)
    year = models.SmallIntegerField('年份')

    class Meta:
        db_table = 'grade'
#views.py
def page_grade(request):
    """ 学生成绩的统计 """
    # 练习1:求某个学生期末成绩的总和
    grade_list = Grade.objects.filter(student_name='张三')
    total = grade_list.aggregate(total_score=Sum('score'))
    print(total)
    # 练习4:求每个学生期末成绩的总和
    stu_list = Student.objects.annotate(total=Sum('stu_grade__score'))

    return render(request, 'page_grade.html', {
        'total': total,
        'stu_list': stu_list
    })

模型事务处理

  • 自动模式
from diango.db import transaction 
@transaction.atomic()
def do_register(request):
  user = UserModel.create(username='zhangsan',password='XXX')
  userLoginHistory = UserLoginHistoryModel.create(user=user ,userName***='会报错的位置')
return HttpResponse('ok')
  • 手动模式
from diango.db import transaction 
#@transaction.atomic()
def do_register(request):
 #放弃自动提交事务
 transaction.set_autocommit(False)
  try:
     user = UserModel.create(username='zhangsan',password='XXX')
     userLoginHistory = UserLoginHistoryModel.create(user=user,userName***='会报错的位置')
     user.save()
     userLoginHistory.save()
     transaction.commit()
  return HttpResponse('ok')
except Exception as e:
    transaction.roolback()
  return HttpResponse('error')
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 227,818评论 6 531
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 98,185评论 3 414
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 175,656评论 0 373
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 62,647评论 1 309
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 71,446评论 6 405
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 54,951评论 1 321
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 43,041评论 3 440
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 42,189评论 0 287
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 48,718评论 1 333
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 40,602评论 3 354
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 42,800评论 1 369
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 38,316评论 5 358
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 44,045评论 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 34,419评论 0 26
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 35,671评论 1 281
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 51,420评论 3 390
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 47,755评论 2 371

推荐阅读更多精彩内容