day-62Django
ORM自己写的多对多
models.py: class Boy(models.Model): name = models.CharField(max_length=32, null=True) class Girl(models.Model): nick = models.CharField(max_length=32, null=True) class Love(models.Model): b = models.ForeignKey("Boy", null=True) g = models.ForeignKey("Girl", null=True) class Meta: unique_together = [ #联合唯一索引的方法 ('b', 'g') ] views.py: #1. 查询和 勾洋 约会的 姑娘 res = models.Boy.objects.filter(name='勾洋').first() # ### 反向查询 love中的相亲记录 love_list = res.love_set.all() ## <QuerySet [<Love: Love object>, <Love: Love object>]> for obj in love_list: # ### 正向查询 girl表中的nick print(obj.g.nick) #2.查询和 勾洋 约会的 姑娘 res = models.Love.objects.filter(b__name='勾洋').all() #<QuerySet [<Love: Love object>, <Love: Love object>]> for obj in res: print(obj.g.nick) # 3.查询和 勾洋 约会的 姑娘 res = models.Love.objects.filter(b__name='勾洋').values("g__nick") #filter相当于where,也就是b__name是条件 #values相当于select后面的,是查的结果,也就是g__nick 显示的是对方表的数据
ORM自动生成的多对多
通过 ManyToManyField() 来生成第三张表,但是只能生成两个字段(boy_id 和 girl_id)
models.py: class Boy(models.Model): name = models.CharField(max_length=32, null=True) g = models.ManyToManyField('Girl', null=True) class Girl(models.Model): nick = models.CharField(max_length=32, null=True) views.py: #添加 obj = models.Boy.objects.filter(name='谢增城').first() #找到名字为谢增城的对象 print(obj) ### Boy object obj.g.add(3) #在第三张表中以谢增城的id添加一条姑娘的id(也就是3) #添加多个 obj.g.add(*[1,2]) 添加姑娘id为1和2 #重置 obj.g.set([4]) #在第三张表中谢增城id对应姑娘的id全变为4 #查询 obj = models.Boy.objects.filter(name='谢增城').first() res = obj.g.all() print(res) ## <QuerySet [<Girl: Girl object>, <Girl: Girl object>, <Girl: Girl object>]> for obj in res: print(obj.nick) #查的是Girl表中谢增城对应的姑娘 #删除 obj = models.Boy.objects.filter(name='谢增城').first() obj.g.clear() #删除第三张表谢增城所有记录
ORM高级查询
print(res.query)查询sql语句 #1. in(id为1,2,3) res = models.UserInfo.objects.filter(id__in=[1,2,3]) #2. not in(id除了1,2,3的所有) res = models.UserInfo.objects.exclude(id__in=[1,2,3]) #3. like(name是列名) #where name like 'ze%' 以ze开头的所有的数据 #startswith: 以 某单词开头 #istartswith : 以 某单词开头 忽略要查的大小写 res = models.UserInfo.objects.filter(name__startswith="ze") res = models.UserInfo.objects.filter(name__istartswith="ze") #where name like '%ze' #endswith : 以 某个单词结尾 #iendswith: 以 某单词结尾 忽略要查大小写 res = models.UserInfo.objects.filter(name__endswith='ze') #where name like "%ze%" #contains : 包含某一个单词 #icontains: 包含某一个单词 忽略要查大小写 # models.UserInfo.objects.filter(name__contains='ze') # 4. between.. and..(id 1到2) models.UserInfo.objects.filter(id__range=[1,2]) #5. limit (就是切片) models.UserInfo.objects.all()[开始位置:结束位置] models.UserInfo.objects.all()[0:10] models.UserInfo.objects.all()[10:20] #6. order by res = models.UserInfo.objects.all().order_by('id') # 以id默认升序 res = models.UserInfo.objects.all().order_by('-id','name') #前面加一个 ‘-’ 代表 降序,上面这个是先按id降序,出现相同在按name升序 #7. group by from django.db.models import Count, Max, Min, Sum res = models.UserInfo.objects.values('name').annotate(xxx=Count('id')) #以name进行分组,以id进行分组的依据,xxx是为id取得别名
#如果还要进行二次筛选(having)后面.filter
# SELECT "app01_userinfo"."id", COUNT("app01_userinfo"."name") AS "xxx" # FROM "app01_userinfo" # GROUP BY "app01_userinfo"."id"; #8. only: 只取某一个列的值(值里包含id,可以和valuve进行对比) # SELECT "app01_userinfo"."id", "app01_userinfo"."name", "app01_userinfo"."age" FROM "app01_userinfo" res = models.UserInfo.objects.only('name', 'age').all() # <QuerySet [<UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>, #<UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>]> #9. defer: 除了这几列之外的所有列的值(之外的值怎么写都会包含id那一列) # SELECT "app01_userinfo"."id", "app01_userinfo"."ut_id" FROM "app01_userinfo" res = models.UserInfo.objects.defer('id','name', 'age').all() #10.using: 想要使用哪个数据库, 就将这个数据库的配置名称(配置字典前面的名称)写到using中 #注意,models中需要有模型表 models.UserInfo.objects.all().using("xxxx") #11. 表中总共多少条数据 res = models.UserInfo.objects.count() #12. 拿第一条数据 res = models.UserInfo.objects.first() # 13.拿最后一条数据 res = models.UserInfo.objects.last() # 14.gt lt res = models.UserInfo.objects.filter(id__gt=3) > res = models.UserInfo.objects.filter(id__gte=3) >= res = models.UserInfo.objects.filter(id__lt=3) < res = models.UserInfo.objects.filter(id__lte=3) <= # 15. and操作 res = models.UserInfo.objects.filter(id=1, name='zekai') # 16.or操作 from django.db.models import Q res = models.UserInfo.objects.filter( Q(Q(id=1) | Q(name='zekai')) & Q(name='xxxx') ) # 先前面or,在和后面and # 17. 在原来的基础数据上更新值 from django.db.models import F models.UserInfo.objects.update(age = F('age') + 1) #18.原生sql(不如pymysql) from django.db import connection cursor = connection.cursor() cursor.execute("select * from app01_userinfo where id=%s", [1,]) res = cursor.fetchall() res = cursor.fetchone() #19. 原生sql models.UserInfo.objects.raw('select * from app01_userinfo') 注意: 1. orm能实现的功能, 尽量使用orm实现 2. 不建议大家以后再自己的业务逻辑中, 混着用
插入多条数据 :
obj = [
models.UserInfo(name='zekai', age=12, ut_id=2),
models.UserInfo(name='xxxxx', age=13, ut_id=2),
models.UserInfo(name='dsadsa', age=14, ut_id=1),
models.UserInfo(name='gfdgfdg', age=24, ut_id=2),
models.UserInfo(name='tretre', age=45, ut_id=3),
models.UserInfo(name='gfdgfd', age=42, ut_id=2),
]
models.UserInfo.objects.bulk_create(obj)
xss攻击
全称:
跨站脚本(js)攻击
原因:
用户输入的内容不可控
案例:
<script>1.获取用户的cookie 2. 发送这个cookie到黑客的数据库</script>
views.py: msg = [] def comment(request): 黑客页面 if request.method == 'GET': return render(request, "comment.html") else: comment = request.POST.get('comment') msg.append(comment) return render(request, "comment.html") def show(request): 用户页面 return render(request, 'show.html', {"msg":msg}) comment.html: <form action="/comment/" method="post"> <input type="text" name="comment"> <input type="submit" value="提交"> </form> show.html: <ul> {% for item in msg %} <li>{{ item | safe }}</li> | safe认为用户传的都是安全的 {% endfor %} </ul>
补充:
ut = models.ForeignKey("UserType", null=True, on_delete=models.CASCADE(默认))
CASCADE: 设置级联删除(子删,关联的父也会删除)
SET_NULL : 取消级联删除
'ud__name'=xxx(神奇的双下划线)这个正向查询在.filter也可以用,表示跨表查询限制条件
'ud__name'这个正向查询在.values中,表示跨表要查哪一列