zoukankan      html  css  js  c++  java
  • django之Model(数据表)的增删改查

    一、新闻模型

    class BaseModel(models.Model):
        # 创建时间
        create_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
        # 更新时间
        update_time = models.DateTimeField(auto_now=True, verbose_name="更新时间")
        # 数据是否删除
        # 逻辑删除
        is_delete = models.BooleanField(default=False, verbose_name="逻辑删除")
    
        class Meta:
            # 这个类只是被继承的
            abstract = True
    
    # 新闻
    class News(BaseModel):
        title = models.CharField(max_length=150, verbose_name="文章标题")
        digest = models.CharField(max_length=200, verbose_name="文章摘要")
        content = models.TextField(verbose_name="文章内容")
        clicks = models.IntegerField(default=0, verbose_name="点击量")
        image_url = models.URLField(default="", verbose_name="图片链接")
        tag = models.ForeignKey("Tag", on_delete=models.SET_NULL, null=True)
        # 如果是其他模块的数据库,关联需要使用app_name.model_name
        author = models.ForeignKey("users.User", on_delete=models.SET_NULL, null=True)
    
        class Meta:
            # 默认排序
            ordering = ["-update_time", "-id"]
            # 指明数据库名
            db_table = "tb_news"
            verbose_name = "新闻"
            verbose_name_plural = verbose_name
    
        def __str__(self):
            return f"News({self.id}, {self.title})"

    二、操作

      两种创建的对象:QuerySet(惰性机制)、Manager

      1、添加

    # 方式一
    news = News(title="Python机器学习", 
                digest="...", 
                content="...", 
                )
    news.save()
    
    # 方拾二
    news = News()
    news.title = "Python机器学习"
    news.digest = "..."
    news.content = "..."
    news.save()
    
    # 方式三
    News.objects.create(title="Python机器学习", 
                        digest="...", 
                        content="...",
                        )
    
    
    # 方式四
    # 返回一个元组(查到的数据,是否创建)
    res = News.objects.get_or_create(id=2000)
    print(res)

      2、修改

    # 修改一条
    news = News.objects.get(id=3)
    news.title = "机器学习"
    news.content = "..."
    news.save()
    
    # 修改多条
    News.objects.filter(tag__name="机器学习").update(title="机器学习")

      3、删除

    # 删除一条
    News.objects.get(id=9).delete()
    
    # 删除多条
    News.objects.all().delete()

      4、查找

    # 查询一条,返回模型对象,立即查询
    News.objects.first() # 查询默认第一条数据
    News.objects.last()  # 查询默认最后一条数据
    # 查询不到和查询到多条都会报错,所以一般配合查询主键使用,pk指代主键
    News.objects.get(pk=3)
    
    # 查询多条
    News.objects.all()  # 查询所有
    News.objects.filter(title="Python高级", tag="Python全栈")  # 相当于执行while...and...
    News.objects.exclude(title="Python高级", tag="Python全栈")  # 相当于执行while not (... and ...),与filter相反
    # 切片,惰性机制:如果不计算,就不会执行数据库查询 res = News.objects.all()
    print(res.query)  # 输出数据库查询语句
    res[1:20].all()  # 切片相当于limit
    
    # 多条件OR查询:Q查询
    from django.db.models import Q
    News.objects.filter(Q(name="Python")|Q(title="机器学习"))
    # F查询:我们构造的过滤器只是将字段值与某个字符串常量做比较。如果我们要对两个字段的值做比较,那么就应该使用F查询
    # Django 支持 F() 对象之间以及 F() 对象和常数之间的加减乘除和取模的操作
    # 查询点击量与id相同的新闻
    from django.db.models import F
    News.objects.filter(id=F("clicks"))
    
    # 不仅可以查询,也可以更新值,总而言之,F("field_name")就是获取对应记录的字段值
    News.objects.update(id=F("id")+1)
    # 指定字段查询,返回QuerySet字典列表
    # <QuerySet [{"":"", "", ""}, {"":"", "":""}]>
    News.objects.values("title", "content")
    # 指定字段查询,返回QuerySet对象列表,一定包含主键,比较高效
    # 即使只有三个字段,也可以访问其他字段,只不过是再查询数据库
    # <QuerySet [News(id, title, content), News(id, title, content)]>
    News.objects.only("title", "content")
    # 指定排除字段查询,用法与only同,效果相反
    News.objects.defer("title", "content")
    # 排序
    # 从小到大排序
    News.objects.all().order_by("id")
    # 从大到小排序
    News.objects.all().order_by("-id")
    
    # 查询条件,应用在get、filter、exclude上面
    # 精准查询
    News.objects.get(id__exact=7)
    # 忽略大小写的精准查询
    News.objects.get(id__iexact=7)
    
    # 模糊查询,针对CharField,包含
    News.objects.filter(title__contains="Python")
    # 模糊查询,针对CharField,忽略大小写
    News.objects.filter(title__icontains="Python")
    # 模糊查询,针对CharField,以什么开头
    News.objects.filter(title__startswith="Python")
    # 模糊查询,针对CharField,以什么结尾
    News.objects.filter(title__endswith="Python")
    
    # 比较查询,针对IntegerField,大于
    News.objects.filter(id__gt=2)
    # 比较查询,针对IntegerField,小于
    News.objects.filter(id__lt=2)
    # 范围查询,针对IntegerField,在什么范围之内
    News.objects.filter(id__range=(10, 200))
    
    # 指定迭代条件, 针对IntegerField、CharField
    News.objects.filter(id__in=[1, 2, 4])
    News.objects.filter(title__in=["Python", "Java"])
    
    # 字段值是否为空
    News.objects.filter(title__isnull=True)
    
    # 聚合查询,利用聚合函数
    from django.db.models import Count, Sum, Avg, Max, Min
    # 如果没有指定键名,则默认为field_name__func_name
    # id__avg
    News.objects.aggregate(Avg("id", "tag_id"))
    # 指定键名
    News.objects.aggregate(id_avg=Avg("id"))
    
    # 分组查询(一般分组与聚合函数会连用)
    # 单独的聚合函数是对数据集的某个字段进行聚合
    # 分组加聚合是先分组,再对每个分组的相应字段进行聚合
    # 对每个分类进行分组,在统计每个分类的新闻数量
    Tag.objects.annotate(news_count=Count("news")).values("name", "news_count")
    
    
    # 正向和反向查询
    # 如果两个表具有关联关系,那么无论在哪一个表,我们都能查询到关联的表的信息
    # 查询id为50的新闻的分类
    # 这是多对一的关系
    News.objects.get(id=5).tag.name
    Tag.objects.get(news__id=5).name
    
    # 多对多的关系
    # 学生和课程表
    from django.db.models import Model, ManyToManyField, CharField
    
    
    class Student(Model):
        department = ManyToManyField("Department")
    
    
    class Department(Model):
        name = CharField(max_length=20)
    
    
    # 查询id为5的学生的课程
    Student.objects.get(id=5).department.all()
    
    Department.objects.filter(student__id=5)
    
    # 查询上数学课的所有学生
    # 最终是为了查询学生信息,但是我们连个表都可以查到,多对多中彼此都添加了一个对方的管理器,
    # 只不过一个是显示声明,一个是隐式声明
    
    Student.objects.filter(department__name="math")
    # student_set是默认添加的
    # modelname_set有add、remove、clear、all的功能,不需要save
    Department.objects.get(name="math").student_set.filter()

    三、优化

      优化主要是针对查询的,一般是同样的查询结果,最少的查询次数,这个参考django数据库查询优化文档:https://docs.djangoproject.com/en/3.0/topics/db/optimization/

  • 相关阅读:
    HDU1720 A+B Coming
    HDU1390 ZOJ1383 Binary Numbers
    HDU1390 ZOJ1383 Binary Numbers
    HDU2504 又见GCD
    HDU2504 又见GCD
    HDU1335 POJ1546 UVA389 UVALive5306 ZOJ1334 Basically Speaking
    HDU1335 POJ1546 UVA389 UVALive5306 ZOJ1334 Basically Speaking
    HDU1020 ZOJ2478 Encoding
    HDU1020 ZOJ2478 Encoding
    HDU2097 Sky数
  • 原文地址:https://www.cnblogs.com/loveprogramme/p/12730977.html
Copyright © 2011-2022 走看看