1 ajax和用戶認證組件 ----PIL和session 2 ajax和form組件註冊功能 (1) form請求和ajax上傳文件 form請求: <form action="" novalidate enctype="multipart/form-data"> </form> request.FILES("avatar") ajax: formdata=new FormData() formdata.append("","") $.ajax({ url:"" processData:false, contentType:false data:formdata }) request.FILES("avatar") (2)圖像預覽 (3)form組件: class Userform(forms.Form): user=forms.Charfield() email=forms.Emailfield() def reg(): if request.method=="GET": form=Userform() return render(request,"reg.html",locals()) 在reg.html: 渲染方式: 1 :{{form.as_p}} 2 : {{form.user}} {{form.user.label}} 3 : {%for field in form%} {{field}} {{field.label}} {%endfor%} def reg(): if request.method=="POST": form=Userform(request.POST) if form.is_valid(): form.cleaned_data else: form.errors return ...... (4) media配置: 靜態文件的處理又包括STATIC和MEDIA兩類,這每每容易混淆,在Django裏面是這樣定義的: MEDIA: 指用戶上傳的文件,好比在Model裏面的FileFIeld,ImageField上傳的文件。 STATIC:指服務器本身的文件。 示例: class User(): avatar = models.FileField(upload_to='avatars/', default="/avatars/default.png") if 實例化一個User對象的時候,avatar字段會接收一個文件對象,這個文件對象 會默認保存到項目的根目錄對應的upload_to='avatars/'的位置 配置1: MEDIA_ROOT=os.path.join(BASE_DIR,"blog","media") if 實例化一個User對象的時候,avatar字段會接收一個文件對象,這個文件對象 會默認保存到MEDIA_ROOT對應路徑的upload_to='avatars/'的位置 配置2: settings: MEDIA_URL="/media/" url.py: from django.views.static import serve from cnblog_s9 import settings # media 配置 url(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}), http://127.0.0.1:8000/media/avatars/lufei.jpg 博客系統: 系統首頁 admin:數據庫後臺管理web頁面 我的站點: 查詢 基於對象查詢(子查詢) 基於queryset查詢(join查詢)
def index(request): article_list = Article.objects.all() return render(request, 'index.html',{'article_list':article_list})
# 登陸 顯示 用戶名 ,註銷 , 修改密碼 。。。
# 未登陸 顯示 登陸 , 註冊
<ul class="nav navbar-nav navbar-right"> {% if request.user.username%} <li><a href="">{{ request.user.username }}</a></li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a> <ul class="dropdown-menu"> <li><a href="#">註銷</a></li> <li><a href="#">修改密碼</a></li> <li role="separator" class="divider"></li> <li><a href="#">更換頭像</a></li> </ul> </li> {% else %} <li><a href="">登陸</a></li> <li><a href="">註冊</a></li> {% endif %}
文章列表顯示:以及用戶頭像點擊到站點css
<div class="col-md-7"> <div class="article_list"> {% for article in article_list %} <div class="article_item"> <div><h5><a href="">{{ article.title }}</a></h5></div> <div class="row"> <div class="col-md-2"><a href="/blog/{{ article.user.username }}"><img width="60" height="60" src="/media/{{ article.user.avatar }}" alt=""></a> </div> <div class="col-md-9 desc"> <p>{{ article.desc }}</p> </div> </div> <div class="small"> <span><a href="/blog/{{ article.user.username }}">{{ article.user.username }}</a>發佈於</span> <span>{{ article.create_time|date:'Y-m-d' }}</span> <span class="glyphicon glyphicon-comment"></span>評論({{ article.comment_count }}) {# <span class="glyphicon glyphicon-comment"></span>評論({{ article.comment_set.count }}) #} <span class="glyphicon glyphicon-thumbs-up"></span>贊({{ article.up_count }}) </div> </div> <hr> {% endfor %} </div> </div>
注意點:html
1. img 的 src python
<img width="60" height="60" src="/media/{{ article.user.avatar }}" alt="">
2.小圖標 點贊數 評論數 mysql
<span class="glyphicon glyphicon-comment"></span>評論({{ article.comment_count }})
<span class="glyphicon glyphicon-thumbs-up"></span>贊({{ article.up_count }})
由於:點贊數 評論數 要頻繁的查,若是每次跨表,效率會低!jquery
<span class="glyphicon glyphicon-comment"></span>評論({{ article.comment_set.count }})git
因此 不使用這個,跨表查詢 article.comment_set.count 而是 新加字段 comment_count web
以後,在進行一次數據庫遷移:makemigrations migrateajax
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>index</title> <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.css"> <link rel="stylesheet" href="/static/css/login.css"> <style type="text/css"> .article_item .desc{ margin-left: -40px;} </style> </head> <body> {# 導航條#} <nav class="navbar navbar-inverse"> <div class="container-fluid"> <!-- Brand and toggle get grouped for better mobile display --> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">博客園</a> </div> <!-- Collect the nav links, forms, and other content for toggling --> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav"> <li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li> <li><a href="#">Link</a></li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a> <ul class="dropdown-menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li role="separator" class="divider"></li> <li><a href="#">Separated link</a></li> <li role="separator" class="divider"></li> <li><a href="#">One more separated link</a></li> </ul> </li> </ul> <ul class="nav navbar-nav navbar-right"> {% if request.user.username%} <li><a href="">{{ request.user.username }}</a></li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a> <ul class="dropdown-menu"> <li><a href="#">註銷</a></li> <li><a href="#">修改密碼</a></li> <li role="separator" class="divider"></li> <li><a href="#">更換頭像</a></li> </ul> </li> {% else %} <li><a href="">登陸</a></li> <li><a href="">註冊</a></li> {% endif %} </ul> </div><!-- /.navbar-collapse --> </div><!-- /.container-fluid --> </nav> <div class="container-fluid"> <div class="col-md-2"> <div class="panel panel-primary"> <div class="panel-heading">Panel heading without title</div> <div class="panel-body"> Panel content </div> </div> <div class="panel panel-info"> <div class="panel-heading">Panel heading without title</div> <div class="panel-body"> Panel content </div> </div> <div class="panel panel-warning"> <div class="panel-heading">Panel heading without title</div> <div class="panel-body"> Panel content </div> </div> </div> <div class="col-md-7"> <div class="article_list"> {% for article in article_list %} <div class="article_item"> <div><h5><a href="">{{ article.title }}</a></h5></div> <div class="row"> <div class="col-md-2"><a href="/blog/{{ article.user.username }}"><img width="60" height="60" src="/media/{{ article.user.avatar }}" alt=""></a> </div> <div class="col-md-9 desc"> <p>{{ article.desc }}</p> </div> </div> <div class="small"> <span><a href="/blog/{{ article.user.username }}">{{ article.user.username }}</a>發佈於</span> <span>{{ article.create_time|date:'Y-m-d' }}</span> <span class="glyphicon glyphicon-comment"></span>評論({{ article.comment_count }}) <span class="glyphicon glyphicon-thumbs-up"></span>贊({{ article.up_count }}) </div> </div> <hr> {% endfor %} </div> </div> <div class="col-md-3"> <div class="panel panel-danger"> <div class="panel-heading"> <h3 class="panel-title">Panel title</h3> </div> <div class="panel-body"> Panel content </div> </div> </div> </div> <script src="/static/js/jquery-3.2.1.min.js"></script> <script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script> </body> </html>
3.學習spring
https://www.cnblogs.com/yuanchenqi/articles/8715364.html
http://www.cnblogs.com/yuanchenqi/category/1192114.html
admin : 數據庫後臺管理web頁面;sql
path('admin/', admin.site.urls),
admin.py
from django.contrib import admin # Register your models here. from .models import * admin.site.register(UserInfo) admin.site.register(Blog) admin.site.register(Category) admin.site.register(Tag) admin.site.register(Article) admin.site.register(ArticleDetail) admin.site.register(Article2Tag) admin.site.register(ArticleUpDown) admin.site.register(Comment)
http://127.0.0.1:8000/admin/
# 查
http://127.0.0.1:8000/admin/blog/article/
# 增
http://127.0.0.1:8000/admin/blog/article/add/
# 改
http://127.0.0.1:8000/admin/blog/article/1/change/
# 刪
http://127.0.0.1:8000/admin/blog/article/1/delete/
def homesite(request,username,**kwargs): # 當前站點得用戶對象 user = UserInfo.objects.filter(username=username).first() if not user: return HttpResponse('404') # 當前站點對象 blog = user.blog # 查詢當前站點對應得文章,以及分類,標籤,日期歸檔得文章 if not kwargs: article_list = Article.objects.filter(user=user) else: condition = kwargs.get('condition') param = kwargs.get('param') if condition == 'cate': article_list = Article.objects.filter(user=user, category__title=param) elif condition == 'tag': article_list = Article.objects.filter(user=user, tags__title=param) else: year, month = param.split('-') article_list = Article.objects.filter(user=user).filter(create_time__year=year, create_time__month=month) # 查詢站點全部每個分類 以及 對應得文章數 分組!! from django.db.models import Count # 查詢站點全部每個分類 以及 對應得文章數 分組!! cate_list = Category.objects.filter(blog=blog).annotate(count = Count('article')).values('title','count') # 每個標籤以及對應得文章數 tag_list = Tag.objects.filter(blog=blog).annotate(count=Count('article')).values_list('title', 'count') # 日期歸檔 date_list = Article.objects.filter(user=user).extra( select={"create_ym": "DATE_FORMAT(create_time,'%%Y-%%m')"}).values('create_ym').annotate( c=Count('nid')).values_list('create_ym', 'c') return render(request,'homesite.html',locals())
個人分類 標籤 日期歸檔
<div class="panel panel-info"> <div class="panel-heading">個人分類</div> <div class="panel-body"> {% for cate in cate_list %} {# <p>{{ cate.title }}({{ cate.article_set.all.count }})</p>#} <p><a href="/blog/{{ username }}/cate/{{ cate.title }}">{{ cate.title }}({{ cate.count }})</a></p> {% endfor %} </div> </div> <div class="panel panel-success"> <div class="panel-heading">個人標籤</div> <div class="panel-body"> {% for tag in tag_list %} <p><a href="/blog/{{ username}}/tag/{{ tag.0 }}">{{ tag.0 }}({{ tag.1 }})</a></p> {% endfor %} </div> </div> <div class="panel panel-danger"> <div class="panel-heading">日期歸檔</div> <div class="panel-body"> {% for date in date_list %} <p><a href="/blog/{{ username }}/archive/{{ date.0 }}">{{ date.0 }}({{ date.1 }})</a></p> {% endfor %} </div> </div>
知識點一:
1. url分發,路徑拼接
from django.urls import path,re_path,include
re_path(r'blog/',include('blog.urls')),
urlpatterns = [
re_path('(\w+)',views.homesite)
]
url 分發,路徑拼接: http://127.0.0.1:8090/blog/egon/
2.分組查詢(文章名稱 文章數)
1.個人分類
# 查詢站點全部每個分類 以及 對應得文章數 分組 !!
from django.db.models import Count
cate_list = Category.objects.filter(blog=blog).annotate(count = Count('article')).values('title','count')<p><a href="/blog/{{ username }}/cate/{{ cate.title }}">{{ cate.title }}({{ cate.count }})</a></p>
2.個人標籤
# 每個標籤以及對應得文章數 分組 !!
tag_list = Tag.objects.filter(blog=blog).annotate(count=Count('article')).values_list('title', 'count')<p><a href="/blog/{{ username}}/tag/{{ tag.0 }}">{{ tag.0 }}({{ tag.1 }})</a></p>
3.日期歸檔
# 日期歸檔以及對應得文章個數 (date_format extra() 單表分組)
date_list = Article.objects.filter(user=user).extra(
select={"create_ym": "DATE_FORMAT(create_time,'%%Y-%%m')"}).values('create_ym').annotate(
c=Count('nid')).values_list('create_ym', 'c')<p><a href="/blog/{{ username }}/archive/{{ date.0 }}">{{ date.0 }}({{ date.1 }})</a></p>
知識點二:
1.數據庫得知識:
http://www.cnblogs.com/yuanchenqi/articles/7250680.html
2.DATE_FORMAT() EXTRA
1.data_format()
DATE_FORMAT(date,fmt) # 針對 mysql 依照指定得fmt格式化日期 date 值
strftime(fmt,date) # 針對 sqllite
eg:
SELECT DATE_FORMAT('1999-01-01 12:12:12', '%Y-%m-%d');
# 1999-01-01
2.orm強大:
數據遷移時,數據庫換了,代碼不用動!每次orm翻譯成sql按照引擎翻譯成 mysql .. oracle .. sqlite ..
純sql語句,效率高!
orm提供了接口,能夠寫sql 可是在數據庫遷移時,須要修改!!
3.extra函數:
是orm 開出來得一個 操做sql得接口!!
http://www.cnblogs.com/yuanchenqi/articles/7570003.html
簡介:
extra(select=None, where=None, params=None,
tables=None, order_by=None, select_params=None)
eg:
queryResult=models.Article
.objects.extra(select={'is_recent': "create_time > '2017-09-05'"})
# in sqlite:
article_obj=models.Article.objects
.filter(nid=1)
.extra(select={"standard_time":"strftime('%%Y-%%m-%%d',create_time)"})
.values("standard_time","nid","title")
print(article_obj)
# <QuerySet [{'title': 'MongoDb 入門教程', 'standard_time': '2017-09-03', 'nid': 1}]>
queryResult=models.Article
.objects.extra(where=['nid in (1,3) OR title like "py%" ','nid>2'])
4.extra應用:
queryResult=models.Article.objects.all().extra(select={'xxx': "create_time > '2017-09-05'"})
id title desc create_time
1 a .. 2012-12
2 b .. 2012-11
3 c .. 2012-10
執行完上面 那句話
id title desc create_time xxx
1 a .. 2012-12 0
2 b .. 2012-11 0
3 c .. 2012-10 1
5.日期歸檔得分類:
1.
date_list = Article.objects.filter(user=user).extra(
select={"create_ym":"DATE_FORMAT(create_time,'%%Y-%%m')"}).values('title','create_time','create_ym')
# extra 得結果
<QuerySet [{'create_ym': '2018-06', 'title': 'DNS的主從,轉發與負載功能',
'create_time': datetime.datetime(2018, 6, 4, 6, 0, tzinfo=<UTC>)},
{'create_ym': '2018-06', 'title': 'spring boot 2.0 源碼分析(二)',
'create_time': datetime.datetime(2018, 6, 5, 16, 7, 41, tzinfo=<UTC>)}]>
2.
date_list = Article.objects.filter(user=user).extra(
select={"create_ym":"DATE_FORMAT(create_time,'%%Y-%%m')"}).values('create_ym').annotate(
c = Count('nid')).values_list('create_ym','c')
# extra 分組 得結果: <QuerySet [('2018-06', 2)]>
總結:
用的知識點:
單表分組 queryset.value('').annotate()
queryset.extra()
DATE_FORMAT(date,fmt)
知識點三:
1. 分類、標籤、日期歸檔 對應得文章
1.分類:
http://127.0.0.1:8090/blog/egon/cate/openstack
2.標籤:
http://127.0.0.1:8090/blog/egon/tag/dream
3.日期歸檔:
http://127.0.0.1:8090/blog/egon/archive/2018-06
知識點:
url 分配: 正則匹配,有名分組 **kwargs
urlpatterns = [
re_path('(?P<username>\w+)/(?P<condition>tag|cate|archive)/(?P<param>.*)',views.homesite),
# homesite(request,username=egon,condition=tag,param=python)
re_path('(?P<username>\w+)/$',views.homesite)
]
def homesite(request,username,**kwargs):
# 查詢當前站點對應得文章,以及分類,標籤,日期歸檔得文章
if not kwargs:
article_list = Article.objects.filter(user=user) # 基於queryset查詢 通常用這種方法 效率高
else:
condition = kwargs.get('condition')
param = kwargs.get('param')
if condition == 'cate':
article_list = Article.objects.filter(user=user, category__title=param)
elif condition == 'tag':
article_list = Article.objects.filter(user=user, tags__title=param)
else:
year, month = param.split('-')
article_list = Article.objects.filter(user=user).filter(create_time__year=year, create_time__month=month)
return render(request,'homesite.html',locals())
2. 注意點:
注意:
若是時間對應得文章沒有顯示出來:
需配置:
TIME_ZONE = 'Asia/Shanghai'
USE_TZ = False
Django models經過DateTimeField保存到MySQL的時間的時區問題:
https://blog.csdn.net/win_turn/article/details/53000770
settings:
TIME_ZONE = 'Asia/Shanghai'
USE_TZ = False
# TIME_ZONE = 'UTC'
# USE_TZ = True
源碼:
def now():
# Returns an aware or naive datetime.datetime, depending on settings.USE_TZ.
if settings.USE_TZ:
# timeit shows that datetime.now(tz=utc) is 24% slower
return datetime.utcnow().replace(tzinfo=utc)
else:
return datetime.now()
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>homesite</title> <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.css"> <style type="text/css"> .header{ width: 100%; height: 40px; background-color: #336699; line-height: 40px; font-size: 16px; color: white;} .header p{ margin-left: 15px;} </style> </head> <body> <div class="header"> <p class="title">{{ blog.title }}</p> </div> <div class='container'> <div class="col-md-3"> <div class="panel panel-info"> <div class="panel-heading">個人分類</div> <div class="panel-body"> {% for cate in cate_list %} {# <p>{{ cate.title }}({{ cate.article_set.all.count }})</p>#} <p><a href="/blog/{{ username }}/cate/{{ cate.title }}">{{ cate.title }}({{ cate.count }})</a></p> {% endfor %} </div> </div> <div class="panel panel-success"> <div class="panel-heading">個人標籤</div> <div class="panel-body"> {% for tag in tag_list %} <p><a href="/blog/{{ username}}/tag/{{ tag.0 }}">{{ tag.0 }}({{ tag.1 }})</a></p> {% endfor %} </div> </div> <div class="panel panel-danger"> <div class="panel-heading">日期歸檔</div> <div class="panel-body"> {% for date in date_list %} <p><a href="/blog/{{ username }}/archive/{{ date.0 }}">{{ date.0 }}({{ date.1 }})</a></p> {% endfor %} </div> </div> </div> <div class="col-md-8"> <div class="article_list"> {% for article in article_list %} <div class="article_item"> <div><h5><a href="">{{ article.title }}</a></h5></div> <div class="row"> <div class="col-md-9 desc"> <p>{{ article.desc }}</p> </div> </div> <div class="small"> 發佈於 <span>{{ article.create_time|date:'Y-m-d' }}</span> <span class="glyphicon glyphicon-comment"></span>評論({{ article.comment_count }}) <span class="glyphicon glyphicon-thumbs-up"></span>贊({{ article.up_count }}) </div> </div> <hr> {% endfor %} </div> </div> </div> </body> </html>
models.py
from django.db import models class AuthorDetail(models.Model): nid = models.AutoField(primary_key=True) birthday = models.DateField() telephone = models.BigIntegerField() addr = models.CharField(max_length=64) class Author(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) age = models.IntegerField() # 與AuthorDetail創建一對一的關係 authorDetail = models.OneToOneField(to="AuthorDetail",on_delete=models.CASCADE,related_name='authors') class Publish(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) city = models.CharField(max_length=32) email = models.EmailField() class Book(models.Model): nid = models.AutoField(primary_key=True) title = models.CharField(max_length=32) publishDate = models.DateField() price = models.DecimalField(max_digits=5, decimal_places=2) keepNum = models.IntegerField() commentNum = models.IntegerField() # 與Publish創建一對多的關係,外鍵字段創建在多的一方 publish = models.ForeignKey(to="Publish", to_field="nid",on_delete=models.CASCADE) # 與Author表創建多對多的關係,ManyToManyField能夠建在兩個模型中的任意一個,自動建立第三張表 authors = models.ManyToManyField(to='Author')
orm查詢
基於對象查詢(子查詢)、 基於queryset 和 __ 查詢(join查詢)、 單表分組 、多表分組
from django.shortcuts import render,HttpResponse from app01.models import * def query(request): ###################### 基於對象得跨表查詢 (子查詢)###################### """ 一對多: Book -------> Publish 正向查詢按字段 反向查詢按表名 小寫_set """ # 1.查詢 id=2 得書籍對應得出版社得郵箱 正向 ret = Book.objects.filter(nid=2).first().publish.email # 2.橘子出版社出版過得全部書籍得名字 反向 ret = Publish.objects.filter(name='橘子出版社').first().book_set.all().values('title') """ 多對多: Book -------> Author 正向查詢按字段 反向查詢按表名 小寫_set """ # 1. 查詢金瓶mei全部做者得名字 正向 ret = Book.objects.filter(title='金瓶mei').first().authors.all().values('name') # 2.做者alex 出版過得書籍得個數 反向 ret = Author.objects.filter(name='alex').first().book_set.all().values('title') ret = Author.objects.filter(name='alex').first().book_set.all().count() """ 一對一: Author -------> AuthorDetail 正向查詢按字段 反向查詢按表名 小寫 或者自定義得 related_name='authors' """ # 1.查詢alex得手機號 正向 ret = Author.objects.filter(name='alex').first().authorDetail.telephone # 2.住在煙臺得做者得名字 反向 ret = AuthorDetail.objects.filter(addr='煙臺').first().authors.name ret = AuthorDetail.objects.filter(addr='煙臺') for i in ret: print(i.authors.name) ########################################### # 基於對象得跨表查詢 (子查詢) """ SELECT "app01_book"."nid", "app01_book"."title", "app01_book"."publishDate", "app01_book"."price", "app01_book"."publish_id" FROM "app01_book" WHERE "app01_book"."nid" = 1 ORDER BY "app01_book"."nid" ASC LIMIT 1; args=(1,) SELECT "app01_publish"."nid", "app01_publish"."name", "app01_publish"."city", "app01_publish"."email" FROM "app01_publish" WHERE "app01_publish"."nid" = 1; args=(1,) """ ###################### 基於queryset和__ 得跨表查詢 ###################### """ 正向查詢按字段 反向查詢按表名 """ # 1.查詢 價格爲100 得書籍對應得出版社得郵箱 ret = Book.objects.filter(price=100).values('publish__email') """ values:內部 queryset = Book.objects.filter(price=100) temp = [] for obj in queryset: temp.append({ 'title':obj.title, 'publish_email':obj.publish_email }) temp """ # 2.橘子出版社出版過得全部書籍得名字 ret = Publish.objects.filter(name='橘子出版社').values("book__title") ret = Book.objects.filter(publish__name='橘子出版社').values('title') # 1. 查詢金瓶mei全部做者得名字 ret = Book.objects.filter(title='金瓶mei').values('authors__name') ret = Author.objects.filter(book__title='金瓶mei').values('name') # 2.做者alex 出版過得書籍得個數 ret = Author.objects.filter(name='alex').values('book__title').count() ret = Book.objects.filter(authors__name='alex').values('title').count() # 1.查詢alex得手機號 ret = Author.objects.filter(name='alex').values('authorDetail__telephone') ret = AuthorDetail.objects.filter(authors__name='alex').values('telephone') # 2.住在煙臺得做者得名字 ret = Author.objects.filter(authorDetail__addr='煙臺').values('name') ret = AuthorDetail.objects.filter(addr='煙臺').values('authors__name') ########################################### # 基於queryset和__ 得跨表查詢 """ SELECT "app01_book"."title", "app01_book"."price" FROM "app01_book" INNER JOIN "app01_publish" ON ("app01_book"."publish_id" = "app01_publish"."nid") WHERE "app01_publish"."name" = '人名出版社2' LIMIT 21; args=('人名出版社2',) """ ###################### 分組查詢(annotate) 與 聚合查詢(avg count sum min)###################### # 員工表 emp 部門表 dep
""" 單表分組 sql: select dep,AVG(salary) from emp group by dep ORM查詢 Emp.objects.values('dep').annotate(dep_avg = AVG(salary)).values('dep','dep_avg') 多表分組 sql: select AVG(salary) from emp group by dep_id select dep.name,AVG(emp.salary) from emp inner join dep on (emp.dep_id == dep.id) group by emp.dep_id ORM查詢: Dep.objects.all().annotate(avg = AVG('emp__salary')).values('name','avg') 注:
queryset.annotate: 按着select的字段進行 group by
""" # 1.每一個出版社出版過得書名稱,書得個數 from django.db.models import Count,Avg # ret = Publish.objects.all().annotate() # 每一個出版社對象 被分爲一個組 # select * from publish group by id ret = Publish.objects.all().annotate(book_count = Count('book__title')).values('name','book_count') # 2.每個做者名字以及對應書籍得平均價格 ret = Author.objects.all().annotate(books_avg = Avg('book__price')).values('name','books_avg') # 3.查詢每一本書得名字以及做者得個數 ret = Book.objects.all().annotate(authors_count = Count('authors')).values('title','authors_count') # 單表分組查詢? Book.objects.all().annotate() # 每個book 得 id group by # select 哪一個字段 就按 哪一個字段 group by ret = Book.objects.all().values('title').annotate(c = Count('*')).values('title','c') # SELECT "app01_book"."title", COUNT(*) AS "c" FROM "app01_book" GROUP BY "app01_book"."title"; args=() ########################################### # from django.core import serializers # 將quertset轉化成json # ret = serializers.serialize('json',ret) # return HttpResponse(ret) # import json # return HttpResponse(json.dumps(list(ret),ensure_ascii=False)) print(ret) return HttpResponse(ret)