美文网首页
[后端开发] Django学习笔记

[后端开发] Django学习笔记

作者: 杨山炮 | 来源:发表于2022-07-15 19:14 被阅读0次

djang起步

//安装
pip install django 
//创建项目名
django-admin startproject 项目名(eg:demo)
//启动服务
python manage.py runserver IP
//创建模块
python manage.py startapp  模块名(eg:hello)

Django ORM模型数据类型

安装依赖

pip install mysqlclient
  • 数据库常见数据类型
    • 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')

相关文章

网友评论

      本文标题:[后端开发] Django学习笔记

      本文链接:https://www.haomeiwen.com/subject/xvenmrtx.html