1、 配置文件:
media: avatar = models.FileField(upload_to='avatar') sessiongs MEDIA_ROOT=os.path.join(BASE_DIR,"blog","media","uploads") 文件上传:BASE_DIR/"blog"/"media"/"uploads"/avatar/a.png urls # media 配置 MEDIA_URL="/media/" url(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}), <img src="/media/avatar/a.png">
2、url配置:
url(r'^articles/([0-9]{4})/$', views.year_archive), # year_archive(request,1990) 无名分组 url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive), # year_archive(request,year=1990) 有名分组
3、反向解析:
in urls: url(r'^articles/([0-9]{4})/$', views.year_archive, name='news-year-archive'), url(r'^index/$', views.index, name='Index'), 方式一 in template(模板反向解析): <a href="articles/2012/">2012 Archive</a> <a href="{% url 'news-year-archive' 2012 %}">2012 Archive</a> 方式二 in views(视图函数反向解析): from django.core.urlresolvers import reverse from django.http import HttpResponseRedirect #return redirect("/index/") # hard code return HttpResponseRedirect(reverse('Index'))
4、视图函数:
请求对象---request: 1、HttpRequest.body: 请求元数据 2、HttpRequest.path:一个字符串,表示请求的路径组件(不含域名) 3、HttpRequest.method 5、HttpRequest.GET 6、HttpRequest.POST 7、HttpRequest.FILES 8、HttpRequest.user : 一个 AUTH_USER_MODEL 类型的对象
响应对象: return HttpResponse("") # 返回字符串实例 return render(request,"template",{"":""}) # 返回字符串实例 (**********) return redirect("/index/") # 重定向 (**********)
5、模板语言:
views:
def foo(): name="yuan" l=[111,222,333] d={"info":[obj1,obj2]} return render(request,"index.html",locals())
1、变量:{{name}}
---深度查询 句点符 {{l.0}} {{d.info.0.name}} ----过滤器:{{name|date:"Y-m-d"}}
2、标签
{%for i in l%} {{ i }} {%empty%} <p>没有符合条件的书籍</p> {%endfor%} -------- {%if name == "yuan"%} <p>真帅</p> {%elif ...%} {%endif%}
3、继承模板:
(1) base.html : {%block con%}{%end block con%} (2) index.html: {% extends "base.html"%} 继承 {%block con%} {{block.super}} 模板盒子中内容 {%end block con%} 覆盖
6、models(模型) -----ORM
映射关系:
sql中表名--------------python的类名 sql中表的字段----------python的类属性 sql中表的记录----------python的类对象 class Article(models.Model): nid = models.BigAutoField(primary_key=True) title = models.CharField(max_length=50, verbose_name='文章标题') read_count = models.IntegerField(default=0)
单表操作:
添加操作 views: #方法1: article_obj=models.Article.objects.create(nid=1,title="yuan",read_count=12) # create方法返回的是当前创建的文章对象 #方法2: article_obj=models.Article(nid=1,title="yuan",read_count=12) article_obj.save() 删除: models.Article.objects.filter(title="python").delete() # 默认级联删除 修改: models.Article.objects.filter(title="python").update(read_count=F("read_count")+10) 查询API: <1> all(): 查询所有结果 #QuerySet <2> filter(**kwargs): 它包含了与所给筛选条件相匹配的对象 #QuerySet <3> get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个, 如果符合筛选条件的对象超过一个或者没有都会抛出错误。# model对象 <5> exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象 #QuerySet <4> values(*field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列 model的实例化对象,而是一个可迭代的字典序列 #QuerySet <9> values_list(*field): 它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列 #QuerySet <6> order_by(*field): 对查询结果排序 #QuerySet <7> reverse(): 对查询结果反向排序 #QuerySet <8> distinct(): 从返回结果中剔除重复纪录 #QuerySet <10> count(): 返回数据库中匹配查询(QuerySet)的对象数量。 # int <11> first(): 返回第一条记录 # model对象 <12> last(): 返回最后一条记录 # model对象 <13> exists(): 如果QuerySet包含数据,就返回True,否则返回False
querySet支持链式操作:
models.Article.objects.all().filter().values().distinct().count()
QuerySet数据类型:
1、可切片,可迭代 [obj,....] 2、惰性查询: articles_list=models.Article.objects.all() 使用articles_list,比如if articles_list,这时转换sql语句 3、缓存机制 articles_list=models.Article.objects.all() for i in articles_list: print(i.title) # hit the database for i in articles_list: print(i.title) # not hit the database ============================================== for i in models.Article.objects.all(): print(i.title) # hit the database for i in models.Article.objects.all(): print(i.title) # hit the database 4、优化查询 articles_list=models.Article.objects.all().iterator() for i in articles_list: print(i.title) # hit the database for i in articles_list: print(i.title) # 无结果
连表操作:
表关系:
class UserInfo(AbstractUser): # settings: AUTH_USER_MODEL = "blog.UserInfo" """ 用户信息 """ nid = models.BigAutoField(primary_key=True) nickname = models.CharField(verbose_name='昵称', max_length=32,null=True) telephone = models.CharField(max_length=11, blank=True, null=True, unique=True, verbose_name='手机号码') avatar = models.FileField(verbose_name='头像', upload_to='avatar', default="avatar/default.png") create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True) class Blog(models.Model): """ 站点信息 """ nid = models.BigAutoField(primary_key=True) title = models.CharField(verbose_name='个人博客标题', max_length=64) site = models.CharField(verbose_name='个人博客后缀', max_length=32, unique=True) theme = models.CharField(verbose_name='博客主题', max_length=32) user = models.OneToOneField(to='UserInfo', to_field='nid') class Category(models.Model): nid = models.AutoField(primary_key=True) title = models.CharField(verbose_name='分类标题', max_length=32) blog = models.ForeignKey(verbose_name='所属博客', to='Blog', to_field='nid') class Article(models.Model): nid = models.BigAutoField(primary_key=True) title = models.CharField(max_length=50, verbose_name='文章标题') desc = models.CharField(max_length=255, verbose_name='文章描述') # category字段: 与Article对象关联的category对象 category = models.ForeignKey(verbose_name='文章类型', to='Category', to_field='nid', null=True) # user字段:与Article对象关联的user字段 user = models.ForeignKey(verbose_name='所属用户', to='UserInfo', to_field='nid') # tags字段: 与Article对象关联的所有的标签对象集合 tags = models.ManyToManyField( to="Tag", through='Article2Tag', through_fields=('article', 'tag'), ) class ArticleDetail(models.Model): nid = models.AutoField(primary_key=True) content = models.TextField(verbose_name='文章内容', ) article = models.OneToOneField(verbose_name='所属文章', to='Article', to_field='nid') class Article2Tag(models.Model): # 中介模型 nid = models.AutoField(primary_key=True) article = models.ForeignKey(verbose_name='文章', to="Article", to_field='nid') tag = models.ForeignKey(verbose_name='标签', to="Tag", to_field='nid') class Tag(models.Model): nid = models.AutoField(primary_key=True) title = models.CharField(verbose_name='标签名称', max_length=32) blog = models.ForeignKey(verbose_name='所属博客', to='Blog', to_field='nid')
关联表的添加记录操作:
1、创建一篇文章对象: user_obj=models.UserInfo.objects.get(nid=1) category_obj=models.Category.objects.get(nid=2) #################一对多关系绑定######################### # 方式1: article_obj=models.Article.objects.create(nid=5,title="招呼亚星"....,user=user_obj,category=category_obj) # 方式2: article_obj=models.Article.objects.create(nid=5,title="招呼亚星"....,user_id=1,category_id=2) ''' Article: nid title user_id category_id 5 招呼亚星 1 2 ''' ############################多对多关系绑定######################### if 没有中介模型: tags = models.ManyToManyField("Tag") ''' ORM创建的第三张表: Article2tags: nid article_id tag_id 1 5 1 2 5 2 ''' 实例:给article_obj绑定kw1,kw2的标签 tag1=Tag.objects.filter(title=kw1).first() tag2=Tag.objects.filter(title=kw2).first() article_obj.tags.add(tag1,tag2) # article_obj.tags.add(*[tag1,tag2]) article_obj.tags.add(1,2) article_obj.tags.add(*[1,2]) 解除关系: article_obj.tags.remove(tag1,tag2) article_obj.tags.clear() 重置关系: article_obj.tags.clear() article_obj.tags.add(tag1,tag2) ===== article_obj.tags.set(tag1,tag2) if 有中介模型: tags = models.ManyToManyField( to="Tag", through='Article2Tag', through_fields=('article', 'tag'), ) class Article2Tag(models.Model): # 中介模型 nid = models.AutoField(primary_key=True) article = models.ForeignKey(verbose_name='文章', to="Article", to_field='nid') tag = models.ForeignKey(verbose_name='标签', to="Tag", to_field='nid') 绑定多对多的关系,有中介模型,不能再使用article_obj.tags.add(),remove()等方法; 只能用Article2Tag表进行实例对象。 实例:给article_obj绑定kw1,kw2的标签: models.Article2Tag.objects.create(tag_id=1,article_id=5) models.Article2Tag.objects.create(tag_id=2,article_id=5)
关联表的查询操作
基于对象查询(子查询):
一对多的查询: 实例1:查询主键为4的文章的分类名称(正向查询,按字段) article_obj=models.Article.objects.get(nid=4) print(article_obj.category.title) SELECT * FROM "blog_article" WHERE "blog_article"."nid" = 4; // category_id=2 SELECT * FROM "blog_category" WHERE "blog_category"."nid" = 2; 实例2:查询用户yuan发表过的所有的文章(反向查询,表名_set) yuan=models.UserInfo.objects.get(username="yuan") book_list=yuan.article_set.all() # QuerySet 多对多的查询: 实例3:查询主键为4的文章的标签名称(正向查询,按字段) article_obj=models.Article.objects.get(nid=4) tag_list=article_obj.tags.all() # 是通过Article2Tag找到tag表中关联的tag记录 for i in tag_list: print(i.title) 实例4:查询web开发的这个标签对应的所有的文章(反向查询,按表名_set) tag_obj=models.Tag.objects.get(title="web开发") article_list=tag_obj.article_set.all() for i in article_list: print(i.title) 实例5:查询web开发的这个标签对应的所有的文章对应的作者名字 tag_obj=models.Tag.objects.get(title="web开发") article_list=tag_obj.article_set.all() for article in article_list: print(article.user.username)
基于QuerySet跨表查询 正向查询,按字段 ;反向查询,按表名(join查询)
一对多的查询: 实例1:查询主键为4的文章的分类名称 models.Article.objects.filter(nid=4).values("category__title") models.Category.objects.filter(article__nid=4).values("title") 实例2:查询用户yuan发表过的所有的文章 models.UserInfo.objects.filter(username="yuan").values(article__title) models.Article.objects.filter(user__username="yuan").values("title") 多对多的查询: 实例3:查询主键为4的文章的标签名称(正向查询,按字段) models.Article.objects.filter(nid=4).values("tags__title") models.Tag.objects.filter(article__nid=4).values("title") 实例4:查询web开发的这个标签对应的所有的文章(反向查询,按表名_set) models.Article.objects.filter(tags__title="web开发").values("title") models.Tag.objects.filter(title="web开发").values("article__title") 实例5:查询web开发的这个标签对应的所有的文章对应的作者名字 models.Tag.objects.filter(title="web开发").values("article__user__username") models.UserInfo.objects.filter(article__tags__title="web开发").values("username")
聚合查询与分组查询:
聚合查询: # 查询所有书籍的平均价格 Book.objects.all().aggregate(Avg('price'))
分组查询: #查询每一个出版社出版过的名字以及出版书籍个数 sql: select publish.name,Count(book.name) from Book inner join publish on book.pub_id=publish.id group by publish.name