Django规范化编程3

Task6.5 了解元类

又又又又到了喜闻乐见的吃水不忘挖井人环节https://www.cnblogs.com/ellisonzhang/p/10513238.html

关键概念: 元类是创造类的类,在Python中万物皆可对象,对象是类的实例化可以由类来创建,所以类可以由源类来实例化

Python创建类的方法 type, 一个古老而强大函数,在类的创建中被调用,用来创建出一个类

# type(类名, 父类的元组(针对继承的情况,可以为空),包含属性的字典(名称和值))     用法

# 覆写一个魔术方法
>>> def __str__(self):
...     return self.name
...
# 用Student源类(None)新建一个类,并赋值和方法
>>> Studentss = type('Student',(),{'name':None,'School':'第二实验小学','__str__':__str__})
# 赋值name
>>> students2 = Studentss()
>>> students2.name = '小可爱'
# 上面覆写了魔术方法,可以直接打印self.name
>>> print(students2)
小可爱

由此我们可以看出,Type可以是所有类的源类

我们不仅可以用type使用源类,也可以在类的定义的时候使用魔术方法定义源类,如:写一个类的时候为其添加__metaclass__属性,定义了__metaclass__就定义了这个类的元类

但是问题是,我们在______metaclass______中放什么代码合适,说到底既然一个类是被实例化出来的,那他的元类应该咋写

实际上我们刚刚已经见到了一个万类元类:Type, 我们的metaclass,也就是元类只要放置type, type的子类或能调用type的类即可(return 为type)

我们可以用含type的函数做元类, 用type的子类做元类, 但是这里我用Python3还原博客写的源类的实例代码时结果完全不一致,不知道是不是因为Python3和Python2的结果有如此的大病

那为什么要学这个呢,因为在Django中Model的API是基于元类设计的,唉。不过搞懂了元类,你就能理解Model的源码(Model是由元类ModelBase创建的,ModelBase元类你就可以理解了)

Task7 了解模型类中的objects是啥

课程链接放出来,这一段确实挺抽象的:https://www.bilibili.com/video/BV1UE411L7Fy?p=3

默认情况下: 模型类会创建一个django.db.models.manager.Manage类的对象,赋给objects。。Manage类是BaseManage.from_queryset(QuerySet) 也就是一个查询结果集对象, 也是QuerySet的子/孙类 。可以从QuerySet中拿到数据库记录。

因此我们在模型中可以覆写objects(必须是manager类型,不然。。)

# models.py
objects = models.Manager()

但是objects能干什么?刚刚我们说过Manager是一个查询结果集对象,因此我们可以在模型类中利用objects进行查询,objects可以进行几乎所有的查询

# models.py
class Player(models.Model):
	virture_name = models.CharField(default = 'GodForever')
 	objects = models.Manager()    # 正确的写法
 	
Task8 objects过滤器
# views 完成一个Player等级的过滤
def find_level(request:HttpRequest):
# 通过等级来过滤玩家
	level_judge = request.Get.get('level',20)
	level_judge = int(level_judge)
	# 设置过滤条件, 大于等于: classname__gte,小于等于_lte, 更多过滤法则请移步官网
	Player = PlayerEntity.objects.filter(level__gte=level_judge,
                                        level__lte = 25).all()
    return render(request,'object_fliter1.html',locals())

# 自己设置一下路由,咱就不写了直接开冲

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传在这里插入图片描述

可以看到筛选出10到25级的范围了

过滤器有两种,一种是fliter 就是上面用的选择 * 范围之内的, 一种是 exclude, 选择 * 范围之外的。注 :Django的object支持链式查找,及支持 PlayerEntity.objects.filter(a).exclude(b).filter©.filter(d)的写法

# object还可以直接用raw 插入sql语句条件
Player = PlayerEntity.objects.raw('Select * from player_Inform Where level>20')
# 需要注意,此时返回的对象为RawQuerySet 本身就是set集合,不需要all

# 同时我们也可已使用orderby进行排序,还有些其他参数可以自己去官网或随便试试,目录叫做:QuerySet方法
Player = PlayerEntity.objects.filter(level__gte=level_judge,
                                        level__lte = 25).all().order_by('level')
Task9 F与Q的用法

首先了解我们的F与Q是什么

F对象,可以将自己的属性作为条件值,主要用于模型类的 A 字段属性与 B 字段属性两者的比较。简单来说,F就是拿到当前属性的某一字段值, 并且支持运算.eg.F

from django.db.models import F
# views.py
# 比如这样的应用场景,因为游戏的更新维护或者说系统崩掉了,表示步长给全体玩家等级加15级
def Jiangli(request:HttpRequest):
    PlayerEntity.objects.update(level= F('level')+15)
    Player = list(PlayerEntity.objects.all().values())
    print(Player)
    return render(request,'F_try.html',locals())

# 没错我又又又又没有把定义子路由的细节给你们

在这里插入图片描述

效果如图,成功自增

Q 对象相比 F 对象更加复杂一点,它主要应用于包含逻辑运算的复杂查询(and:& or:| 非:~ )。Q 对象把关键字参数封装在一起,并传递给 filter、exclude、get 等查询的方法。

在filter中虽然可以做很多约束,不过级联查询条件都是and 而不是or ,Q对象可以做到all查询。举个例子就很好理解

from django.db.models import Q
# 我们的目标是找一些资深玩家,指伊西俄老玩家和新秀玩家,游玩时间长或等级高的玩家
def Special_Player(request:HttpRequest):
    Super_Player = list(PlayerEntity.objects.filter(Q(level__gte = 20)|Q(play_valu__gte =20)).values())
    print(Super_Player)
    
# 因为不想再新建html模板直接print了,虽然浏览器有无reponse的报错但是可以再输出看到,成功
[{'id': 1, 'virture_name': 'Son_Bitch', 'level': 26, 'play_valu': 38.7, 'profile_picture': None}, {'id': 2, 'virture_name': 'MyLover', 'level': 23, 'play_valu': 14.4, 'profile_picture'
: None}, {'id': 3, 'virture_name': "'小可爱'", 'level': 44, 'play_valu': 13.8, 'profile_picture': 't11.png'}]
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值