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数据的时候,它帮你作校验,若是校验不经过就拒绝此次请求
相关文章
相关标签/搜索