2018.7.10個人ブログ記事=>ORMによる分類とORMの組み込み関数の作成


昨日の登録締め切り
実はMySqlとつながっている部分が悪くて、この部分は簡単で、まずユーザーがfromを通じて送ってきた顔のファイルを保存することです.
"""
      
"""
file = request.FILES.get('avatar')
file_path = os.path.join('static/img', file.name)
with open(file_path, 'wb') as f:
	for chunk in file.chunks():
		f.write(chunk)  #    

次に、ユーザーが入力した値を対応するデータベースのテーブルに保存し、ORMで簡単に書くことができます.
v = request.POST
result = models.UserInfo.objects.create(username=v.get('username'),password=v.get('password'),email=v.get('email'),nickname=v.get('username'),avatar='/' + file_path, )

対応するブログへのアクセスに必要なルーティング構成の問題
私たちがブログのホームページにアクセスするときは、情報を登録する必要はありません.http://127.0.0.1:8000/blog/***.htmlなどのウェブサイトは対応するブログに入って必要な情報を得ることができるので、ルートを設定するときに、ブロガーの名前をブログのウェブサイトの一部として使用するためのパラメータを追加しました.
re_path('^blog/(\w+).html$', views.blog)

処理関数に、(w+)のパラメータを受信するためのnameパラメータを追加します.
def blog(request, name):
    return render(request, 'blog.html', {'name': name})

これにより、ルーティングされたファイルが簡単に解決され、後で最適化される可能性があります.
個人用ページブログ記事のタイプ分類(一対一)
ブログのホームページを書く前に、ブログの文章の分類部分をページに展示しておきたいと思います.
まず対応するブログオブジェクトを取得します.これはよく取得され、上のnameパラメータを利用して簡単にできます.
blog = models.Blog.objects.filter(site=name).first()

まず、現在のブログの分類を利用して、対応するすべての文章を逆方向に検索し、検索した文章の数を計算すると、対応する分類の下の文章の数を得ることができます.
#         
cate_list = models.Category.objects.filter(blog=blog)
for item in cate_list:	#         
    c = item.article_set.all().count()	#                           
    print(item,c)

しかし、この方法には悪い点があります.それは、頻繁にデータベースを検索する必要があります.これにより、後期にサーバの反応速度が大幅に遅くなります.
GroupByを使用して必要なすべての値を一度にクエリすることを考えました.SQL文は次のとおりです.
select category_id, count(nid) as c from article where blog_id = *** group by category_id

しかし、ORMで行うにはvaluesとannotate関数を組み合わせてパケットクエリの目的を達成する必要があります.
category_list = models.Article.objects.filter(blog=blog).values('category_id','category__title',).annotate(c=Count('nid'))  #           ,            

個人用ページブログ記事のタグ分類(複数対複数)
数少ない理屈:
models.Article2Tag.objects.filter(tag__blog=blog).values('tag_id','tag__title').annotate(c=Count('id'))

個人ホームページブログ記事の時間分類
時間の分類に注意しなければならない点は実は時間のフォーマットの変換で、MySQLの中のDATE_を利用することができますFORMAT()関数は具体的に私の小さい知識の総括を参照することができて、SQL文は以下の通りです:
select date_format(create_time,'%Y-%m'),count(nid) as c from article where blog_id=1 group by date_format(create_time,'%Y-%m')

しかし、ORMではどのようにしますか.extra関数を使用して、テーブルに追加のフィールドを追加して、クエリーをグループ化する目的を達成することができます.
date_list = models.Article.objects.filter(blog=blog).extra(select={'c': "date_format(create_time,'%%Y-%%m')"}).values('c').annotate(ct=Count('nid'))

Django ORM内蔵関数と関数のカスタマイズ
ORM内蔵関数には、主に基礎関数と時間関数の2種類があります.
#     
Cast, Coalesce, Concat, ConcatPair, Greatest, Least, Length, Lower, Now, Substr, Upper,
#     
Extract, ExtractDay, ExtractHour, ExtractMinute, ExtractMonth,ExtractSecond, ExtractWeekDay, ExtractYear, Trunc, TruncDate, TruncDay,TruncHour, TruncMinute, TruncMonth, TruncSecond, TruncYear,

これらの基礎関数はannotate関数で呼び出されます.たとえば、次のようになります.
from django.db.models import FloatField
from django.db.models import Value
v = models.Article.objects.annotate(c=functions.Cast('nid', FloatField()))
v = models.Article.objects.annotate(c=functions.Coalesce('title','summary'))
v = models.Article.objects.annotate(c=functions.Concat('nid','title','summary'))
v = models.Article.objects.annotate(c=functions.Concat('nid','title','summary',Value('666')))
v = models.Article.objects.annotate(c=functions.Greatest('nid','num'))
v = models.Article.objects.annotate(c=functions.Length('title'))
v = models.Article.objects.annotate(c=functions.Substr('title',1,1))

すべての関数の機能は以下のように列挙されている(以下、この大神のブログを参照).
# ###########      ###########

    # 1. Concat,       
    # v = models.UserInfo.objects.annotate(c=Cast('pwd', FloatField()))

    # 2. Coalesce,    ,          
    # v = models.UserInfo.objects.annotate(c=Coalesce('name', 'pwd'))
    # v = models.UserInfo.objects.annotate(c=Coalesce(Value('666'),'name', 'pwd'))

    # 3. Concat,  
    # models.UserInfo.objects.update(name=Concat('name', 'pwd'))
    # models.UserInfo.objects.update(name=Concat('name', Value('666')))
    # models.UserInfo.objects.update(name=Concat('name', Value('666'),Value('999')))

    # 4.ConcatPair,  (     )
    # v = models.UserInfo.objects.annotate(c=ConcatPair('name', 'pwd'))
    # v = models.UserInfo.objects.annotate(c=ConcatPair('name', Value('666')))

    # 5.Greatest,       ;least        ;
    # v = models.UserInfo.objects.annotate(c=Greatest('id', 'pwd',output_field=FloatField()))

    # 6.Length,    
    # v = models.UserInfo.objects.annotate(c=Length('name'))

    # 7. Lower,Upper,    
    # v = models.UserInfo.objects.annotate(c=Lower('name'))
    # v = models.UserInfo.objects.annotate(c=Upper('name'))

    # 8. Now,      
    # v = models.UserInfo.objects.annotate(c=Now())

    # 9. substr,   
    # v = models.UserInfo.objects.annotate(c=Substr('name',1,2))

# ########### ########### # 1. , :Extract, ExtractDay, ExtractHour, ExtractMinute, ExtractMonth,ExtractSecond, ExtractWeekDay, ExtractYear, # v = models.UserInfo.objects.annotate(c=functions.ExtractYear('ctime')) # v = models.UserInfo.objects.annotate(c=functions.ExtractMonth('ctime')) # v = models.UserInfo.objects.annotate(c=functions.ExtractDay('ctime')) # # v = models.UserInfo.objects.annotate(c=functions.Extract('ctime', 'year')) # v = models.UserInfo.objects.annotate(c=functions.Extract('ctime', 'month')) # v = models.UserInfo.objects.annotate(c=functions.Extract('ctime', 'year_month')) """ MICROSECOND SECOND MINUTE HOUR DAY WEEK MONTH QUARTER YEAR SECOND_MICROSECOND MINUTE_MICROSECOND MINUTE_SECOND HOUR_MICROSECOND HOUR_SECOND HOUR_MINUTE DAY_MICROSECOND DAY_SECOND DAY_MINUTE DAY_HOUR YEAR_MONTH """ # 2. , :Trunc, TruncDate, TruncDay,TruncHour, TruncMinute, TruncMonth, TruncSecond, TruncYear # v = models.UserInfo.objects.annotate(c=functions.TruncHour('ctime')) # v = models.UserInfo.objects.annotate(c=functions.TruncDate('ctime')) # v = models.UserInfo.objects.annotate(c=functions.Trunc('ctime','year'))

ORMカスタム関数の書き方:
from django.db.models.functions.base import Func
    class CustomeFunc(Func):
        function = 'DATE_FORMAT'
        template = '%(function)s(%(expressions)s,%(format)s)'

        def __init__(self, expression, **extra):
            expressions = [expression]
            super(CustomeFunc, self).__init__(*expressions, **extra)

    v = models.UserInfo.objects.annotate(c=CustomeFunc('ctime',format="'%%Y-%%m'"))

  
転載先:https://www.cnblogs.com/yu-jie/p/9289908.html