• Django杂记


    Django ORM执行原生SQL

    # extra
    # 在QuerySet的基础上继续执行子语句
    # extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None)
    
    # select和select_params是一组,where和params是一组,tables用来设置from哪个表
    # Entry.objects.extra(select={'new_id': "select col from sometable where othercol > %s"}, select_params=(1,))
    # Entry.objects.extra(where=['headline=%s'], params=['Lennon'])
    # Entry.objects.extra(where=["foo='a' OR bar = 'a'", "baz = 'a'"])
    # Entry.objects.extra(select={'new_id': "select id from tb where id > %s"}, select_params=(1,), order_by=['-nid'])
    
    举个例子:
    models.UserInfo.objects.extra(
                        select={'newid':'select count(1) from app01_usertype where id>%s'},
                        select_params=[1,],
                        where = ['age>%s'],
                        params=[18,],
                        order_by=['-age'],
                        tables=['app01_usertype']
                    )
                    """
                    select 
                        app01_userinfo.id,
                        (select count(1) from app01_usertype where id>1) as newid
                    from app01_userinfo,app01_usertype
                    where 
                        app01_userinfo.age > 18
                    order by 
                        app01_userinfo.age desc
                    """
    
    
    # 执行原生SQL
    # 更高灵活度的方式执行原生SQL语句
    # from django.db import connection, connections
    # cursor = connection.cursor()  # cursor = connections['default'].cursor()
    # cursor.execute("""SELECT * from auth_user where id = %s""", [1])
    # row = cursor.fetchone()
    
    ORM 执行原生SQL的方法
    

    Django终端打印SQL语句

    在Django项目的settings.py文件中,在最后复制粘贴如下代码:

    LOGGING = {
        'version': 1,
        'disable_existing_loggers': False,
        'handlers': {
            'console':{
                'level':'DEBUG',
                'class':'logging.StreamHandler',
            },
        },
        'loggers': {
            'django.db.backends': {
                'handlers': ['console'],
                'propagate': True,
                'level':'DEBUG',
            },
        }
    }

    即为你的Django项目配置上一个名为django.db.backends的logger实例即可查看翻译后的SQL语句。 

    在Python脚本中调用Django环境

    import os
    
    if __name__ == '__main__':
        os.environ.setdefault("DJANGO_SETTINGS_MODULE", "BMS.settings")
        import django
        django.setup()
    
        from app01 import models
    
        books = models.Book.objects.all()
        print(books)
    

    多对多的三种方式

    多对多的方式:
    1. ORM自动帮我创建第三张表

    models.ManyToManyField(to="Book", related_name="authors")

    2. 自己创建第三张表, 利用外键分别关联作者和书

    # 书
    class Book(models.Model):
        title = models.CharField(max_length=32)
        publish_date = models.DateField(auto_now_add=True)
        price = models.DecimalField(max_digits=5, decimal_places=2)
        # 创建外键,关联publish
        publisher = models.ForeignKey(to="Publisher")
    
        def __str__(self):
            return self.title
    
    
    # 作者
    class Author(models.Model):
        name = models.CharField(max_length=32)
        age = models.IntegerField()
        phone = models.IntegerField()
    
        def __str__(self):
            return self.name
    
    
    # 自己动手 创建作者和书关联的第三张表
    # 此时 在ORM层面 作者和书就没有多对多的关系了
    class Author2Book(models.Model):
        id = models.AutoField(primary_key=True)
        # 作者id
        author = models.ForeignKey(to="Author")
        # 书id
        book = models.ForeignKey(to="Book")
    
        class Meta:
            # 建立唯一约束
            unique_together = ("author", "book")
    

      关联查询比较麻烦,因为没办法使用ORM提供的便利方法

    3. 自己创建第三张表,使用ORM 的ManyToManyFiled()

    from django.db import models
    
    # Create your models here.
    
    
    from django.db import models
    
    # Create your models here.
    from django.db import models
    
    # Create your models here.
    
    
    # 出版社
    class Publisher(models.Model):
        name = models.CharField(max_length=32)
        city = models.CharField(max_length=32)
    
        def __str__(self):
            return self.name
    
    
    # 书
    class Book(models.Model):
        title = models.CharField(max_length=32)
        publish_date = models.DateField(auto_now_add=True)
        price = models.DecimalField(max_digits=5, decimal_places=2)
        # 创建外键,关联publish
        publisher = models.ForeignKey(to="Publisher")
    
        def __str__(self):
            return self.title
    
    
    # 作者
    class Author(models.Model):
        name = models.CharField(max_length=32)
        age = models.IntegerField()
        phone = models.IntegerField()
        # 通过through,告诉Django通过哪张表建立关系,through_fields来指定使用我创建的第三张表来构建多对多的关系
        books = models.ManyToManyField(to="Book", through="Author2Book", through_fields=("author", "book",))
        # 第一个字段: 多对多设置在哪一张表里, 第三张表通过什么字段找到这张表(Author) 就把这个字段写在前面
        detail = models.OneToOneField(to="AuthorDetail")
    
        def __str__(self):
            return self.name
    
    
    # 自己动手 创建作者和书关联的第三张表
    # 此时 在ORM层面
    class Author2Book(models.Model):
        id = models.AutoField(primary_key=True)
        # 作者id
        author = models.ForeignKey(to="Author")
        # 书id
        book = models.ForeignKey(to="Book")
    
        # memo
        memo = models.CharField(max_length=64, null=True)
    
        class Meta:
            # 建立唯一约束
            unique_together = ("author", "book")
    
    
    # 作者详情
    class AuthorDetail(models.Model):
        # 爱好
        hobby = models.CharField(max_length=32)
        # 地址
        addr = models.CharField(max_length=128)
    

      使用此种方式创建多对多表的时候,没有 add() remove() 等方法

    我们应该用哪种?
    看情况:
    1. 如果你第三张表没有额外的字段,就用第一种
    2. 如果你第三张表有额外的字段,就用第三种或第一种

    csrf简单用法

    什么是CSRF ————跨站请求伪造
    问题:
    1. 钓鱼网站的页面和正经网站的页面对浏览器来说有什么区别? (页面是怎么来的?)
    钓鱼网站的页面是由 钓鱼网站的服务端给你返回的
    正经网站的网页是由 正经网站的服务端给你返回的

    2. Django中内置了一个专门处理csrf问题的中间件
    django.middleware.csrf.CsrfViewMiddleware

    这个中间件做的事情:
    1. 在render返回页面的时候,在页面中塞了一个隐藏的input标签
    用法:
    我们在页面上 form表单 里面 写上 {% csrf_token %}
    <input type="hidden" name="csrfmiddlewaretoken" value="8gthvLKulM7pqulNl2q3u46v1oEbKG7BSwg6qsHBv4zf0zj0UcbQmpbAdijqyhfE">

    2. 当你提交POST数据的时候,它帮你做校验,如果校验不通过就拒绝这次请求

  • 相关阅读:
    #ifdef的用法
    修改WordPress中上传附件2M大小限制的方法/php+iis上传附件默认大小修改方法
    没有找到libufun.lib,因此这个应用程序未能启动。重新安装应用程序可能会修复此问题。
    JAVA安卓和C# 3DES加密解密的兼容性问题
    使用 Repeater 控件,每隔N条数据输出另外的格式
    Forms表单登陆,动态获取web.config里面的cookies配置
    SQL Server中索引使用及维护
    动态绑定easyui datagrid列名
    Spring Hibernate多数据源配置
    SSH异常处理
  • 原文地址:https://www.cnblogs.com/wlx97e6/p/9881488.html
Copyright © 2020-2023  润新知