美文网首页
[后端开发] 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