Django框架技术总结-学会即可具备Web开发能力(二)

接着上一篇的分享,我们继续学习Django,本篇将从CURD深度解析、F和Q的使用方法、原声SQL语句查询、模型类、app内部模块等几个方面讲述。

为了更好的学习,我专门创建了一个技术交流,有兴趣的可以加WX(19524662948),我拉大家入群,一起探寻程序人生。

目录

一、CURD深度解析

1.1 模型类的objects

1.2 filter和exclude查询

1.3QuerySet对象 

1.4 聚合函数类 

二、F和Q的用法 

三、原生SQL语句查询 

4、模型类

4.1 显性创建模型类

4.2 一对一关系

4.3 一对多、多对一的关系 

4.4 多对多关系

五、app内部模板

六、结束语 


一、CURD深度解析

1.1 模型类的objects

正常情况下,我们可以不用在模型类中创建objects对象。因为默认情况,django.db.models.Manager这个已经帮我创建好了,如果字段中实在有objects,那我们必须创建objects为Manager对象,Manager类实际是QuerySet类的子类。如下:

class Test(models.Model):
     test_name = models.CharField(max_length=20)
     test_info = models.CharField(max_length=20)
     objects = models.Manager()  # 正确的写法

1.2 filter和exclude查询

通过filter和exclude可以筛选出我们想要的数据集合,从而满足业务需求。用法如下:

Test.objects.filter(属性名__条件=条件值)
Test.objects.filter(属性名=条件值)
Test.objects.filter(属性名__时间属性__条件=条件值)

查询中的条件如下:

gt:大于     lt:小于     gte:大于等于    lte:小于等于

contains:包含xx字符串  (i)startswith:是否以x字符串开头  (i)endswith:是否以x字符串结尾

isnull:是否为空  isnotnull是否不为空

in:是否在xxx里面(xxx可以是字符串、列表、字典等等)

查询中的时间属性如下:

年月日时分秒:year、month、day、hour、minute,second

1.3QuerySet对象 

QuerySet对象字面意思级查询集合,其目的就是创建我们的模型类(class Test)在元类中创建django.db.models.Manager类的对象,即为QuerySet。QuerySet是可以被迭代的。

返回QuerySet的对象的方法有:

filter  exclude  all  values  order_by():分组查  count():统计数据个数  exists():判断数据是否存在

1.4 聚合函数类 

其实在1.3中count的用法也可以归为聚合函数类的使用,其原理是django.db.models.聚合函数与QuerySet中的aggregate()组合使用。举例:

Test.objects.aggregate(Min(test_score))  # 查询测试分数最低的一条数据,结合aggregate使用

二、F和Q的用法 

F的作用就是筛选出有计算的,或者是数字更新的数据,原理是django.db.models.F,举例:

# 将测试分数更新为四舍五入
Test.objects.update(test_score=round(F('test_score'),2))

Q的作用可以用来解决多个条件之间的逻辑关系,与或非,原理是django.db.models.Q,举例:

 # 查询分数低于50的,或高于90的测试用例
 test_q = Test.objects.filter(Q(test_score__lte=50) | Q(t_score=90)).values()

三、原生SQL语句查询 

大家可以发现,今天前面三张主要就是学习怎么筛选得到我们想要的数据。为什么这一块的方法很发杂很多呢,就是因为我们的数据库里面存在各种各样的数据,为了最终的数据是我们想要的数据,就要应对不同数据的特性,学习解决这一类数据方法,从而提高开发效率。下面我们就学习原生SQL语句查询我们想要的数据。

原生SQL语句查询主要针对复杂的查询,通过QuerySet以及上面两章的介绍已经无法查询的时候,则使用原生SQL查询,不过一般情况下,上面的两个基本就可以解决百分之八十的查询问题。

这里插播一曲,说道原生SQL那肯定离不开SQL语句了。我将在后面几天巩固一下Mysql方面的知识,顺便更新几篇Mysql的博客,感兴趣的朋友们可以持续关注,等待文章的产出。

QuerySet提供两种原生SQL语句查询:

QuerySet.raw()

条件:查询的字段必须是模型类中声明的字段,且必须存在主键列 。查询的结果是RawQuerySet类对象,可以迭代,元素类型是模型类对象。

raw_queryset = Test.objects.raw('select id, name,test_score from tb_test where test_score < %s  order by test_score DESC LIMIT %s, 10', (10, 0))

for raw in raw_queryset:
    print(raw)

QuerySet.extra()

条件:extra()扩展查询, 针对QuerySet查询结果集中,额外增加查询条件或排序等相关操作。返回结果还是QuerySet对象

qs1 = Test.objects.extra(where=['test_score < %s'], params=['10'])
qs2 = Test.objects.extra(where=['test_score < %s or test_name like %s'], params=['20', 'agv'])

 扩展:使用django.db.connection数据库连接对象进行原生SQL查询(这种方法感兴趣的朋友也可持续关注我,后面有时间分享并讲解)

4、模型类

4.1 显性创建模型类

class TestManager(models.Manager):
     def get_queryset(self):
     		 return super().get_queryset().filter(Test.Q(test_score>50))

4.2 一对一关系

通过models.OneToOneField(联系的模型类, on_delete=models.CASCADE)这样去建立

class RealProfile(models.Model):
    # 声明一对一的关联关系
    user = models.OneToOneField(User,
                                verbose_name='账号',
                                on_delete=models.CASCADE)

    real_name = models.CharField(max_length=20,
                                 verbose_name='真实姓名')
    number = models.CharField(max_length=30,
                              verbose_name='证件号')

    real_type = models.IntegerField(verbose_name='证件类型',
                                    choices=((0, '身份证'),
                                             (1, '护照'),
                                             (2, '驾驶证')))

    image1 = models.ImageField(verbose_name='正面照',
                               upload_to='user/real')
    image2 = models.ImageField(verbose_name='反面照',
                               upload_to='user/real')

以上是我们辅表:实名认证表 主表为User表,通过user字段联系起一对一之间的关系。当我们联系起这样的关系后,就可以通过辅表找到主表的数据了。

u = RealProfile.objects.filter(real_name='xx').first()
u.user.phone # 直接访问主表对象的数据

4.3 一对多、多对一的关系 

# 声明水果商品与购物车的关系表
class FruitCartEntity(models.Model):
    cart = models.ForeignKey(CartEntity,
                             on_delete=models.CASCADE,
                             verbose_name='购物车')

    fruit = models.ForeignKey(FruitEntity,
                              on_delete=models.CASCADE,
                              verbose_name='水果名')
    cnt = models.IntegerField(verbose_name='数量',
                              default=1)

    def __str__(self):
        return self.fruit.name +':'+self.cart.no

    @property
    def price1(self):
        # 属性方法在后台显示时没有verbose_name, 如何解决?
        return self.fruit.price  # 从获取主的对象属性

    @property
    def price(self):
        # 属性方法在后台显示时没有verbose_name, 如何解决?
        return round(self.cnt*self.fruit.price, 2)

    class Meta:
        db_table = 't_fruit_cart'
        verbose_name_plural = verbose_name = '购物车详情表'

通过Meta类申明我们当前商品表与购物车详情表之间的关系。每个用户购物车只有一个,但是购物车里面的商品可以有多个。

# 主读取多个从对象的信息
login_u = User.objects.get(pk=1)
 # 查询当前用户的购物车中的所有商品及数量相关的信息
cart_fruits = login_u.cartentity.fruitcartentity_set.all() 
for fruit_cart in cart_fruits:
    print(fruit_cart.fruit.name, fruit_cart.fruit.price, fruit_cart.cnt)

首先登陆进来的用户login_u,每个用户都有一个购物车 login_u.cartentity,因为购物车和水果商品在模型类中存在一对多的关系,所以在购物车详情表里就可以通过fruitcartentity_set联系起水果商品表,从而对水果商品表数据进行交互。例如买卖数量的加减,金额的确定等。

4.4 多对多关系

通过models.ManyToManyField(联系的模型类,db_table:被联系起的表别名,related_name:联系的主外键,verbose_name:被联系的表名),需要第三方表的外键来实现。

需求:用户收藏商品, 需要建立第三方表,完成用户收藏多个商品, 或一个商品被多位用户收藏。

在水果商品表中,添加如下关联关系:

# 默认情况下,反向引用的名称是当前类的名称(小写)_set
# 可以通过related_name 来指定
# db_table='t_collect' 使用第三张表建立fruit和user的多对多关系
users = models.ManyToManyField(UserEntity,
                               db_table='t_collect',
                               related_name='fruits',
                               verbose_name='收藏用户列表')

通过水果商品表,联系起User表和收藏表之间的关系。根据需求我们可以知道,用户可以收藏多个商品,每个商品也可以被多个用户收藏,其中间的桥梁就是商品,所以在水果商品表申明多对多的字段,其联系起User表,被联系表别名 t_collect,联系的主外键关系fruits(收藏表中肯定有fruits这个字段最为水果商品表的外键),被联系的表名verbose_name。下面我们模拟用户收藏商品:

u1 = User.objects.get(pk=1)
u1.fruits.add(FruitEntity.objects.get(pk=1))
u1.fruits.add(FruitEntity.objects.get(pk=2))

五、app内部模板

到这一步基本上后端Django的一些知识点就已经讲完了,分享的不是很细致。但是大体的学习思路和还是罗列的非常清晰的。我们在开发web项目的时候,不仅仅是需要后端开发,还需要前端的开发。Django作为一个MTV模式的开发框架,自然有对T的开发,但是如果是都写在pycharm里面,也就是说整个项目MTV都在同一个项目包下,我们把这种开发模式叫做前后端不分离,不推荐使用,这里做一个简单介绍,介绍各模块中的T,也就是我们的模板。

每个app下都可以增加templates目录,存放它自己的模板文件

内部的模板templates目录,不需要在settings.py中设置

如果app模块之外存在templates目录,且在settings.py中已设置,则加载模板时,则优先从此目录中加载模板文件。

我还是推荐大家使用前后端分离的开发方式,后端用某个框架去搭建,前端用前端的框架去搭建。管理项目也十分方便。

注意:在进行项目是前后端分离的开发方式的时候,我们要具备的技能有以下几点:

1.熟悉一个后端框架

2.熟悉一个前端框架

3.熟悉网络协议、特别是请求和响应的过程

为了方便学习,我将我自己总结好的资源将放在下一篇博客中,感兴趣的可以下载查看。内容主要是:

1.Django入门

2.Vue入门

3.交互前后端HTTP协议

4.前后端的交互流程

宏观性的了解了这样的交互流程之后,学起来可能会更加轻松一些。

六、结束语 

Django的分享到这里也就结束了,可能分享的不是很好。因为我自我也能感觉到,有很多细枝末节的知识点没有整理出来,但是目前来说,还没有一个好的思路去总结那些细小的知识点。因为真的知识点太多太多了,后面有时间,遇到问题的话会当方面的拿一些知识点来总结。创作不易,记得点赞收藏,给博主一个小小的支持吧。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

戒酒的李白-Lisage

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值