6.3-Django第三天

官方文档:https://docs.djangoproject.com/zh-hans/2.1/

一、F和Q的用法

1.1 F的字段条件

可以将自己的属性作为条件值

from django.db.models import F
Store.objects.filter(id=F('years'))  # 查询Store
案列:

dajango.db.models.F 用于获取字段的值并参于计算或作业更新条件

# 新年:全场水果打8.8折扣
FruitEntity.objects.update(price=F('price') * 0.88) 
且还支持运算
Store.objects.filter(id=1).update(years=F('years')+5)
1.2 Q的多条件

可以进行逻辑运算

  • & 与 | 或 ~ 非
Store.objects.all().filter(Q(years=1)|Q(years=2))
Store.objects.all().filter(~Q(years=1))
Store.objects.all().filter(Q(years__gt=1)&Q(years__lt=2))

二、原生的SQL语句查询

针对复杂查询来说,通过Queryset查询不是特别方便,则使用原生的SQL查询。

  • QuerySet 提供了两种原生SQL查询:
  1. QuerySet.raw()

    • 要求:查询的字段必须是模型类中声明的字段,且必须存在主键列。查询的结果是RawQuerySet类对象,可以迭代,元素类型是模型类对象。
    raw_queryset = FruitEntity.objects.raw('select id, name, price from t_fruit where price< %s order by price desc LIMIT %s, 5',(5,0))
    
    for fruit in raw_queryset:
         print(fruit)
    

    另外,查询sql语句中可以使用"%s"或“%(name)s”占位符,在其它可以使用元组或字典参数传值

    raw_queryset = FruitEntity.objects.raw('select id, name, price from t_fruit where price< %(price)s order by price desc LIMIT %(page)s, 5',{'price':10,'page':0})
    
  2. QuerySet.extra()

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

    qs1=FruitEntity.objects.extra(where=['price>%s or name like %s', 'source=%s'], params=['2', '果''成都']).
    queryset.all()
    
  • 使用django.db.connection数据库连接对象进行原生SQL查询

    connection对象表示与数据库连接的对象,可以通过connection连接对象获取游标cursor再通过cursor的exec cute()/fetchall()/rowcount()相关方法或函数来执行原生的SQL和执行的结果。

    from django.db import connection
    cursor=connection.cursor()
    cursor.execcute('select * from t_fruit')
    for row in cursor.fetchall():
        print(row)
    
    cursor.execute('update t_fruit set price=2 where id=1')print(cursor.rowcount)connection.commit()  #提交更新
    

​ 》》》from mainapp.models import FruitEntity

1.写出models.CharField字段类的约束
max_length  最大字符个数primary_key   是否为主键  boolunique   是否唯一  boolnull  数据表中的字段值是否为null   boolblank  站点表单验证数据时是否为空  booldb_column  指定表中的字段名 strdb_index  是否创建当前字段的索引  boolverbose_name  站点页面显示的字段名称 strdefault   默认值
2.写出模型的Meta元信息有哪些
db_table 指定当前模型类对应的表名  strordering  指定哪些字段的排序方式  ['-字段名']verbose_name 指定站点显示类的名字 verbose_name_plural  类名称的复数   默认值verbose_name+"s"unique_together  指定哪些字段组合的唯一索引   tuple,如(('字段1'.'字段2'))app_label   指定当前模型所属的app模块名
3.写出QuerySet的filter()查询条件有哪些?
gt gteltltestartwith/isstartwithendswith/iendswithcontains/icontainsin notinisnullisnotnull

三、模型之间的关系

1.设计订单模型

#在models中做类from django.db import modelsclass BaseModel(models.Model):    create_time = models.DateTimeField(verbose_name='创建时间',                                       auto_now_add=True)    last_time = models.DateTimeField(verbose_name='更新时间',                                     auto_now=True)    class Meta:        abstract = True    # 抽象的模型类,既不会创建表# Create your models here.class OrderModel(BaseModel):    num = models.CharField(max_length=20,                           primary_key=True,                           verbose_name='订单号')    title = models.CharField(max_length=100,                             verbose_name='订单名称')    price = models.DecimalField(max_digits=10,                                decimal_places=2,                                verbose_name='订单金额')    pay_type = models.IntegerField(choices=((0, '余额'),                                            (1, '银行卡'),                                            (2, '微信支付'),                                            (3, '支付宝')),                                   verbose_name='支付方式',                                   default=0)    pay_status = models.IntegerField(choices=((0, '待支付'),                                              (1, '已支付'),                                              (2, '待收货'),                                              (3, '已收货'),                                              (4, '完成'),                                              (5, '取消')),                                     verbose_name='订单状态',                                     default=0)    receiver = models.CharField(verbose_name='收货人',                                max_length=20)    receiver_phone = models.CharField(max_length=11,                                      verbose_name='收货人的手机')    receiver_address = models.TextField(verbose_name='收货人的地址')    def __str__(self):        return self.title    class Meta:        db_table = 't_order'        verbose_name = verbose_name_plural = '订单表'

def str(self): return self. 对应下面页面

2.在主工程中的settings中注册orderapp

3.在admin.py里注册站点

from django.contrib import adminfrom orderapp.models import OrderModel# Register your models here.class OrderAdmin(admin.ModelAdmin):    list_display = ('num', 'title', 'price', 'pay_type', 'pay_status',                    'receiver', 'receiver_phone', 'receiver_address')    fields = ('num', 'title', 'price', 'pay_type', 'pay_status',              'receiver', 'receiver_phone', 'receiver_address')admin.site.register(OrderModel, OrderAdmin)

4.迁移文件

python manage.py makemigrationspython manage.py migrate

5.运行

python manage.py runserever
3.1扩展:显性方式创建objects
# 声明QuerySet或Manager的子类class OrderManager(models.Manager):    # 获取查询结果集对象QuerySet    def get_queryset(self):        return super().get_queryset().filter(~models.Q(pay_status=5))  # 状态码不是5的objects = OrderManager()   # 显性创建 objects
# 统计2018年全年销售总额from orderapp.models import OrderModelfrom django.db.models import SumOrderModel.objects.filter(create_time__year=2022).aggregate(total_price=Sum('price'))
3.2一对一关系

一对一的关系可以通过models.OnetoOneField(关联模型类, on_delete=models.CASCADE)建立

on_delete 除了CASCADE级联删除之外,还有model.SET_NULL级联设置为空

# 用户表的实名认证
class RealProfile(models.Model):
    # 声明1对1的关联关系
    user = models.OneToOneField(UserEntity, verbose_name='账号', on_delete=models.CASCADE)
    real_name = models.CharField(max_length=20,
                                 verbose_name='真实姓名')
    number = models.CharField(max_length=18,
                              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')

    def __str__(self):
        return self.real_name

    class Meta:
        db_table = 't_user_profile'
        verbose_name = '实名认证表'
        verbose_name_plural = verbose_name

主表:用户表 从表:实名认证表

从表对象获取主表的数据时

from mainapp.models import RealProfile, UserEntity
u1 = RealProfile.objects.filter(real_name='小向').frist()
u1.user.phone    # 直接访问主表对象的数据

主表中获取从表的数据

login_u1=UserEntity.objects.get(id=4)
# 对象.关联模型类全小写名称.属性
login_u1.realprofile.number  #以隐形的方式读取从表的数据  realprofile 一对一的关系模型类名的名称(全小写)
3.3一对多或多对一的关系 (ForeignKey 一对多)ManytoManyFiled
# 声明水果商品与购物车的关系表
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

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

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

    class Meta:
        db_table = 't_fruit_cart'
        verbose_name = verbose_name_plural = '购物车详情表'
# 从读取主对象的信息    def price1(self):        # 属性方法在后台显示时没有verbose_name,如果解决?        return round(self.fruit.price, 2)  # 从获取主的对象属性    # 主对象读取多个从对象的信息login_u = UserEntity.objects.get(id=5)#查询当前用户的购物车中的所有商品及数量相关的信息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)
3.4 多对多

models.ManyToManyFiled

作业:

1.练习今天的知识点
2.完成订单模型类的拆分(多个模型)及相关模型

3.预习:

  • 模型类的面向对象

  • 模板语法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值