• ORM详细操作


     
     
     
    1. ORM常用字段和属性

     1. AutoField(primary_key=True)
    2. CharField(max_length=32)
    3. IntgerField()
    4. DateField()
    5. DateTimeField()
    1. auto_now_add    --> 创建的时候自动填充当前时间
    2. auto_now        --> 每次修改的时候自动把当前时间更新
                    
    2. 关系字段

    1. ForeignKey(to="类名",related_name=“xx”)   --> 1对多  ,外键通常设置在多的那一边,related_name是反向查询使用
    2. ManyToMany(to="类名",related_name="xx")    --> 多对多,通常设置在正向查询多的那一边
     
    3. ORM一般操作

     
    1. 必知必会13条
    1. 返回QuerySet对象的
                        1. all()
                        2. filter()
                        3. values()
                        4. values_list()
                        5. exclude()
                        6. order_by()
                        7. reverse()
                        8. distinct()
    2. 返回具体对象的
                        1. get()
                        2. first()
                        3. last()
    3. 返回布尔值的
                        1. exists()
    4. 返回具体数值的
                        1. count()
     
    2. 单表查询的双下划线
                    1. models.Book.objects.filter(id__gt=1)    #查询id大于1的book对象
                    2. models.Book.objects.filter(id__in=[1,2,3])    #查询id在1,2,3中的的所有对象
                    3. models.Book.objects.filter(id__range=[1,5])    #查询id在1到5的范围的对象
                    4. models.Book.objects.filter(title__contains="沙河")    #查询书名中包含沙河的所有对象
                    5. models.Book.objects.filter(title__icontains="沙河")    #查询书名中包含沙河的所有对象,忽略大小写
                    6. models.Book.objects.filter(title__startswith="沙河")    #查询书名是以沙河开头的所有对象
                    7. models.Book.objects.filter(title__endswith="沙河")    #查询书名是以沙河结尾的所有对象
                    8. models.Book.objects.filter(publish_date__year=2017)    #查询出版社出版年份是2017年的所有书的对象
                    9. models.Book.objects.filter(publish_date__month=2)    #查询出版社月份是2月的所有书的对象
     
    3. 外键的跨表查询
    a.正向查找
    1. 基于对象
    book_obj = models.Book.object.get(id=1)
    book_obj.publisher.name
    2. 基于双下划线的
    models.Book.objects.filter(id=1).values("publisher__name")      #  先获取id为1的书的对象,然后到publisher的出版社对象中找name属性,values中一定要加引号和双下划线
    如:
    ret = models.Book.objects.filter(id=1).values('publisher__name')
    print(ret)
    <QuerySet [{'publisher__name': '清华大学出版社'}]>
    b.反向查找(由出版社查书)
                        1. 基于对象
                            publisher_obj = models.Publisher.objects.get(id=1)
                            默认反向查找的时候是表名加_set
                                publisher_obj.book_set.all()
                            如果在外键中设置了related_name="books"
                                publisher_obj.books.all()
                        
                        2. 基于双下划线
                            models.Publisher.objects.filter(id=1).values("book__title")     #这里也是用的book
                            如果配置了related_query_name="books"
                            models.Publisher.objects.filter(id=1).values("books__title")
    这里有个很大的疑惑,为什么反向查找时,表名Book不可以,要用小写的book呢,这个没有定义的:
    class publisher(models.Model):
        id = models.AutoField(primary_key=True)
        name = models.CharField(null=False, max_length=20)
     
    class Book(models.Model):
        id = models.AutoField(primary_key=True)
        title = models.CharField(max_length=64, null=False, unique=True)
        price = models.DecimalField(max_digits=5, decimal_places=2, default=99.99)
        publisher = models.ForeignKey(to='publisher')
     
    publisher_obj = models.publisher.objects.get(id=9)
    ret = publisher_obj.book_set.all()    #如果用了Book会报错,没有这个属性
    print(ret)
     
    返回的对象??
    <QuerySet [<Book: Book object>, <Book: Book object>]>
     
    4. 分组和聚合
                    1. 聚合
                        from django.db.models import Avg, Sum, Max, Min, Count
                        models.Book.objects.all().aggregate(Avg("price"))
                    2. 分组
                        book_list = models.Book.objects.all().annotate(author_num=Count("author"))    #先拿出所有的Book对象,然后按id分组,接着拿id去统计作者数量
    #分组详解  
    ret = models.Book.objects.all().annotate(author_num=Count('authors'))    #这里的authors是写了related_query_name='authors'
    for i in ret:
        print(i.author_num)
    #返回的对象和sql语句
    (0.000) SELECT @@SQL_AUTO_IS_NULL; args=None
    (0.069) SELECT `app_publisher_book`.`id`, `app_publisher_book`.`title`, `app_publisher_book`.`price`, `app_publisher_book`.`publisher_id`, `app_publisher_book`.`author_id`, COUNT(`app_publisher_author_book`.`author_id`) AS `author_num` FROM `app_publisher_book` LEFT OUTER JOIN `app_publisher_author_book` ON (`app_publisher_book`.`id` = `app_publisher_author_book`.`book_id`) GROUP BY `app_publisher_book`.`id` ORDER BY NULL; args=()
    3
    3
    3
    1
    [Finished in 1.7s]
     
    5. F和Q
                    1. 当需要字段和字段作比较的时候用F查询
                    2. 当查询条件是 的时候 用Q查询,因为默认的filter参数都是且的关系
     
    6. 事务
    保证数据的原子性操作!!!
    import os
     
    if __name__ == '__main__':
        os.environ.setdefault("DJANGO_SETTINGS_MODULE", "BMS.settings")
        import django
        django.setup()
     
        import datetime
        from app01 import models
     
        try:
            from django.db import transaction    #导入事务模块
            with transaction.atomic():    #使用with关键字,如果下面的内容出错,程序会自动回滚,把执行过的sql语句回滚到最原始的状态
                new_publisher = models.Publisher.objects.create(name="火星出版社")
                models.Book.objects.create(title="橘子物语", publish_date=datetime.date.today(), publisher_id=10)  # 指定一个不存在的出版社id
        except Exception as e:
            print(str(e))
     
    7. 执行原生的SQL语句(了解即可)
     
    CSRF跨站请求伪造

            1. 钓鱼网站的页面和正经网站的页面对浏览器来说有什么区别? (页面是怎么来的?)
                钓鱼网站的页面是由 钓鱼网站的服务端给你返回的
                
                正经网站的网页是由 正经网站的服务端给你返回的
                
                
            2. Django中内置了一个专门处理csrf问题的中间件
                django.middleware.csrf.CsrfViewMiddleware
                
                这个中间件做的事情:
                    1. 在render返回页面的时候,在页面中塞了一个隐藏的input标签
                    
                    用法:
                        我们在页面上 form表单 里面 写上 {% csrf_token %}
                        
                    <input type="hidden" name="csrfmiddlewaretoken" value="8gthvLKulM7pqulNl2q3u46v1oEbKG7BSwg6qsHBv4zf0zj0UcbQmpbAdijqyhfE">
                    
                    2. 当你提交POST数据的时候,它帮你做校验,如果校验不通过就拒绝这次请求
     
  • 相关阅读:
    nginx 配置以及常用命令
    django TypeError: 'module' object is not callable
    Django Meta内部类选项
    安装MySQL后要做的事
    MySQL存储引擎
    kali linux 2018.2 mysql密码修改后无效,外部无法连接问题。
    Django中CSS加载background url('')问题
    升级OPENSSH 和 OPENSSL
    Git创建仓库的方法(github翻译)
    Git标签(版本)管理
  • 原文地址:https://www.cnblogs.com/changwoo/p/9568524.html
Copyright © 2020-2023  润新知