from django.db import models # Create your models here. from django.contrib.auth.models import AbstractUser class UserInfo(AbstractUser): """ 用戶信息 """ nid = models.AutoField(primary_key=True) telephone = models.CharField(max_length=11, null=True, unique=True) avatar = models.FileField(upload_to='avatars/', default="/avatars/default.png") create_time = models.DateTimeField(verbose_name='建立時間', auto_now_add=True) blog = models.OneToOneField(to='Blog', to_field='nid', null=True, on_delete=models.CASCADE) def __str__(self): return self.username class Blog(models.Model): """ 博客信息 """ nid = models.AutoField(primary_key=True) title = models.CharField(verbose_name='我的博客標題', max_length=64) site_name = models.CharField(verbose_name='站點名稱', max_length=64) theme = models.CharField(verbose_name='博客主題', max_length=32) def __str__(self): return self.title 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', on_delete=models.CASCADE) def __str__(self): return self.title 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', on_delete=models.CASCADE) def __str__(self): return self.title class Article(models.Model): nid = models.AutoField(primary_key=True) title = models.CharField(max_length=50, verbose_name='文章標題') desc = models.CharField(max_length=255, verbose_name='文章描述') create_time = models.DateTimeField(verbose_name='建立時間', auto_now_add=True) content = models.TextField() comment_count = models.IntegerField(default=0) up_count = models.IntegerField(default=0) down_count = models.IntegerField(default=0) user = models.ForeignKey(verbose_name='做者', to='UserInfo', to_field='nid', on_delete=models.CASCADE) category = models.ForeignKey(to='Category', to_field='nid', null=True, on_delete=models.CASCADE) tags = models.ManyToManyField( to="Tag", through='Article2Tag', through_fields=('article', 'tag'), ) def __str__(self): return self.title class Article2Tag(models.Model): nid = models.AutoField(primary_key=True) article = models.ForeignKey(verbose_name='文章', to="Article", to_field='nid', on_delete=models.CASCADE) tag = models.ForeignKey(verbose_name='標籤', to="Tag", to_field='nid', on_delete=models.CASCADE) class Meta: unique_together = [ ('article', 'tag'), ] def __str__(self): v = self.article.title + "---" + self.tag.title return v class ArticleUpDown(models.Model): """ 點贊表 """ nid = models.AutoField(primary_key=True) user = models.ForeignKey('UserInfo', null=True, on_delete=models.CASCADE) article = models.ForeignKey("Article", null=True, on_delete=models.CASCADE) is_up = models.BooleanField(default=True) class Meta: unique_together = [ ('article', 'user'), ] class Comment(models.Model): """ 評論表 """ nid = models.AutoField(primary_key=True) article = models.ForeignKey(verbose_name='評論文章', to='Article', to_field='nid', on_delete=models.CASCADE) user = models.ForeignKey(verbose_name='評論者', to='UserInfo', to_field='nid', on_delete=models.CASCADE) content = models.CharField(verbose_name='評論內容', max_length=255) create_time = models.DateTimeField(verbose_name='建立時間', auto_now_add=True) parent_comment = models.ForeignKey('self', null=True, on_delete=models.CASCADE) def __str__(self): return self.content
""" Django settings for cnblogs project. Generated by 'django-admin startproject' using Django 2.1. For more information on this file, see https://docs.djangoproject.com/en/2.1/topics/settings/ For the full list of settings and their values, see https://docs.djangoproject.com/en/2.1/ref/settings/ """ import os # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = '97e0#&=bl*0zl@99!_#4o*6fs=e&3-6@8rdq0clas*hojx6!5z' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True ALLOWED_HOSTS = [] # Application definition INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'blog.apps.BlogConfig', ] MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] ROOT_URLCONF = 'cnblogs.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')] , 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] WSGI_APPLICATION = 'cnblogs.wsgi.application' # Database # https://docs.djangoproject.com/en/2.1/ref/settings/#databases # DATABASES = { # 'default': { # 'ENGINE': 'django.db.backends.sqlite3', # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), # } # } DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql',#數據庫的引擎爲MySQL; 'NAME': 'cnblogs',#要鏈接的數據庫實例的名稱,鏈接前須要已經完成建立; 'USER': 'root',#MySQL數據庫的用戶名; 'PASSWORD': 'Tqtl911!@%*)',#MySQL數據庫的密碼; 'HOST': '47.95.121.154',#MySQL數據庫服務器的IP地址; 'PORT': '3306'#MySQL數據庫的款口號,默認3306; } } # Password validation # https://docs.djangoproject.com/en/2.1/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', }, { 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', }, { 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', }, { 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', }, ] # Internationalization # https://docs.djangoproject.com/en/2.1/topics/i18n/ LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' USE_I18N = True USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/2.1/howto/static-files/ STATIC_URL = '/static/' AUTH_USER_MODEL = 'blog.UserInfo' LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'console':{ 'level':'DEBUG', 'class':'logging.StreamHandler', }, }, 'loggers': { 'django.db.backends': { 'handlers': ['console'], 'propagate': True, 'level':'DEBUG', }, } }
python manage.py makemigrations
python manage.py migrate
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/blog/bs/css/bootstrap.css"> </head> <body> <h3>登陸頁面</h3> <div class="container"> <div class="row"> <div class="col-md-6 col-lg-offset-3"> <form action=""> <div class="form-group"> <label for="user">用戶名</label> <input type="text" id="user" class="form-control"> </div> <div class="form-group"> <label for="pwd">密碼</label> <input type="password" id="pwd" class="form-control"> </div > <input type="button" class="btn btn-default pull-right login_btn" value="submit"> </form> </div> </div> </div> </body> </html>
from django.shortcuts import render # Create your views here. def login(request): return render(request,"login.html")
STATICFILES_DIRS = [ os.path.join(BASE_DIR,"static") ]
PIL:Python Imaging Library,已是Python平臺事實上的圖像處理標準庫了,PIL功能很是強大,且API很是簡單易用。php
因爲PIL僅支持到Python 2.7,加上年久失修,因而一羣志願者在PIL的基礎上建立了兼容的版本,名字叫Pillow,支持最新Python 3.x,又加入了許多新特性,所以,咱們能夠直接安裝使用Pillow。css
pip install pillow
from django.shortcuts import render,HttpResponse,redirect # Create your views here. def login(request): return render(request,"login.html") import random def get_validCode_img(request): def get_random_color(): return (random.randint(0,255),random.randint(0,255),random.randint(0,255)) #方式1-with open方法; # with open("lufei.jpg","rb") as f: # data = f.read() #方式2;pip install pillow; from PIL import Image img = Image.new("RGB",(270,40),color=get_random_color()) with open("validCode.png","wb") as f: img.save(f,"png") with open("validCode.png","rb") as f: data = f.read() return HttpResponse(data)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/blog/bs/css/bootstrap.css"> </head> <body> <h3>登陸頁面</h3> <div class="container"> <div class="row"> <div class="col-md-6 col-lg-offset-3"> <form action=""> {% csrf_token %} <div class="form-group"> <label for="user">用戶名</label> <input type="text" id="user" class="form-control"> </div> <div class="form-group"> <label for="pwd">密碼</label> <input type="password" id="pwd" class="form-control"> </div > <div class="form-group"> <label for="pwd">驗證碼</label> <div class="row"> <div class="col-md-6"> <input type="text" class="valid_code form-control"> </div> <div class="col-md-6"></div> <img width="260" height="45" src="/get_validCode_img/" alt=""> </div> </div> <input type="button" class="btn btn-default pull-right login_btn" value="submit"> </form> </div> </div> </div> </body> </html>
from django.shortcuts import render,HttpResponse,redirect # Create your views here. def login(request): return render(request,"login.html") import random def get_validCode_img(request): def get_random_color(): return (random.randint(0,255),random.randint(0,255),random.randint(0,255)) #方式1-with open方法; # with open("lufei.jpg","rb") as f: # data = f.read() #方式2;pip install pillow; # from PIL import Image # img = Image.new("RGB",(270,40),color=get_random_color()) # with open("validCode.png","wb") as f: # img.save(f,"png") # with open("validCode.png","rb") as f: # data = f.read() #方式3:將數據放置於內存中,加快處理速度; # from PIL import Image # from io import BytesIO # # img = Image.new("RGB",(270,40),color=get_random_color()) # f = BytesIO() # img.save(f,"png") # data = f.getvalue() #方式4:向圖像區域他添加噪點,和字符串; from PIL import Image,ImageDraw,ImageFont from io import BytesIO import random char = str(random.randint(0,9)) img = Image.new("RGB",(270,40),color=get_random_color()) draw = ImageDraw.Draw(img) kumo_font = ImageFont.truetype("static/font/kumo.ttf",size=28) #生成隨機字符串; #方法1: # for i in range(0,5): # import string # random_char = ' '.join(random.sample(string.ascii_lowercase + string.ascii_uppercase,1)) # d4}5c+/m|97e@"16]s # draw.text((i*50+20,5),random_char,get_random_color(),font=kumo_font) #方法2: for i in range(5): random_num = str(random.randint(0,9)) random_lowercase = chr(random.randint(95,122)) random_uppercase = chr(random.randint(65,90)) random_char = random.choice([random_num,random_lowercase,random_uppercase]) draw.text((i*50+20,5),random_char,get_random_color(),font=kumo_font) #進行畫圖 #draw.line() #draw.point() f = BytesIO() img.save(f,"png") data = f.getvalue() return HttpResponse(data)
#給圖片添加上噪點; width = 270 height = 40 for i in range(5): x1 = random.randint(0,width) x2 = random.randint(0,width) y1 = random.randint(0,height) y2 = random.randint(0,height) draw.line((x1,y1,x2,y2),fill=get_random_color()) for i in range(10): draw.point([random.randint(0,width),random.randint(0,height)],fill=get_random_color()) x = random.randint(0,width) y = random.randint(0,height) draw.arc((x,y,x+4,y+4),0,90,fill=get_random_color())
<script src="/static/blog/js/jquery-3.3.1.min.js"></script> <script> //刷新圖片驗證碼; $("#valid_code_img").click(function () { $(this)[0].src+="?" }) </script>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/blog/bs/css/bootstrap.css"> </head> <body> <h3>登陸頁面</h3> <div class="container"> <div class="row"> <div class="col-md-6 col-lg-offset-3"> <form action=""> {% csrf_token %} <div class="form-group"> <label for="user">用戶名</label> <input type="text" id="user" class="form-control"> </div> <div class="form-group"> <label for="pwd">密碼</label> <input type="password" id="pwd" class="form-control"> </div > <div class="form-group"> <label for="pwd">驗證碼</label> <div class="row"> <div class="col-md-6"> <input type="text" class="valid_code form-control"> </div> <div class="col-md-6"> <img width="260" height="45" id="valid_code_img" src="/get_validCode_img/" alt="">
</div> </div> </div> <input type="button" class="btn btn-default pull-right login_btn" value="submit"> </form> </div> </div> </div> <script src="/static/blog/js/jquery-3.3.1.min.js"></script> <script> //刷新圖片驗證碼; $("#valid_code_img").click(function () { $(this)[0].src+="?" }) </script> </body> </html>
from django.shortcuts import render,HttpResponse,redirect # Create your views here. from django.http import JsonResponse def login(request): if request.method == "POST": response = {"user":None,"msg":None} user = request.POST.get("user") pwd = request.POST.get("pwd") valid_code = request.POST.get("valid_code") valid_code_str = request.session.get("valid_code_str") #print("valid_code_str",valid_code_str,type(valid_code_str)) #print("valid_code",valid_code,type(valid_code)) if valid_code.upper() == valid_code_str.upper(): pass else: response["msg"] = "valid code error!" return JsonResponse(response) return render(request,"login.html") import random def get_validCode_img(request): def get_random_color(): return (random.randint(0,255),random.randint(0,255),random.randint(0,255)) #方式1-with open方法; # with open("lufei.jpg","rb") as f: # data = f.read() #方式2;pip install pillow; # from PIL import Image # img = Image.new("RGB",(270,40),color=get_random_color()) # with open("validCode.png","wb") as f: # img.save(f,"png") # with open("validCode.png","rb") as f: # data = f.read() #方式3:將數據放置於內存中,加快處理速度; # from PIL import Image # from io import BytesIO # # img = Image.new("RGB",(270,40),color=get_random_color()) # f = BytesIO() # img.save(f,"png") # data = f.getvalue() #方式4-向圖像區域他添加噪點,和字符串; from PIL import Image,ImageDraw,ImageFont from io import BytesIO import random char = str(random.randint(0,9)) img = Image.new("RGB",(270,40),color=get_random_color()) draw = ImageDraw.Draw(img) kumo_font = ImageFont.truetype("static/font/BASKVILL.TTF",size=28) #保存隨機字符串; valid_code_str = "" #生成隨機字符串; #方法1: for i in range(0,5): import string random_char = ' '.join(random.sample(string.ascii_lowercase + string.ascii_uppercase,1)) # d4}5c+/m|97e@"16]s draw.text((i*50+20,5),random_char,get_random_color(),font=kumo_font) #保存驗證碼字符串; valid_code_str+= random_char #方法2: # for i in range(500): # random_num = str(random.randint(0,9)) # random_lowercase = chr(random.randint(95,122)) # random_uppercase = chr(random.randint(65,90)) # random_char = random.choice([random_num,random_lowercase,random_uppercase]) # draw.text((i*50+20,5),random_char,get_random_color(),font=kumo_font) #進行畫圖; #draw.line() #draw.point() #給圖片添加上噪點; width = 270 height = 40 for i in range(5): x1 = random.randint(0,width) x2 = random.randint(0,width) y1 = random.randint(0,height) y2 = random.randint(0,height) draw.line((x1,y1,x2,y2),fill=get_random_color()) for i in range(10): draw.point([random.randint(0,width),random.randint(0,height)],fill=get_random_color()) x = random.randint(0,width) y = random.randint(0,height) draw.arc((x,y,x+4,y+4),0,90,fill=get_random_color()) print("valid_code_str",valid_code_str) request.session["valid_code_str"] = valid_code_str ''' 一、生成隨機字符串; 二、COOKIE{"sessionid":fdsfdsfds} 三、django-session表生成記錄; ''' f = BytesIO() img.save(f, "png") data = f.getvalue() return HttpResponse(data)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/blog/bs/css/bootstrap.css"> </head> <body> <h3>登陸頁面</h3> <div class="container"> <div class="row"> <div class="col-md-6 col-lg-offset-3"> <form > {% csrf_token %} <div class="form-group"> <label for="user">用戶名</label> <input type="text" id="user" class="form-control"> </div> <div class="form-group"> <label for="pwd">密碼</label> <input type="password" id="pwd" class="form-control"> </div > <div class="form-group"> <label for="pwd">驗證碼</label> <div class="row"> <div class="col-md-6"> <input type="text" class="form-control" id="valid_code"> </div> <div class="col-md-6"> <img width="260" height="45" id="valid_code_img" src="/get_validCode_img/" alt=""> </div> </div> </div> <input type="button" class="btn btn-default pull-right login_btn" value="submit"> </form> </div> </div> </div> <script src="/static/blog/js/jquery-3.3.1.min.js"></script> <script> //刷新圖片驗證碼; $("#valid_code_img").click(function () { $(this)[0].src+="?" }); //登錄過驗證; $(".login_btn").click(function () { $.ajax({ url:"", type:"post", data:{ user:$("#user").val(), pwd:$("#pwd").val(), valid_code:$("#valid_code").val(), csrfmiddlewaretoken:$("[name='csrfmiddlewaretoken']").val(), }, success:function (data) { console.log(data) } }) }) </script> </body> </html>
from django.shortcuts import render,HttpResponse,redirect # Create your views here. from django.http import JsonResponse from django.contrib import auth def login(request): if request.method == "POST": response = {"user":None,"msg":None} user = request.POST.get("user") pwd = request.POST.get("pwd") valid_code = request.POST.get("valid_code") valid_code_str = request.session.get("valid_code_str") #print("valid_code_str",valid_code_str,type(valid_code_str)) #print("valid_code",valid_code,type(valid_code)) if valid_code.upper() == valid_code_str.upper(): user = auth.authenticate(username = user,password = pwd) if user: response["user"] = user.username else: response["msg"] = "用戶名或者密碼錯誤!" else: response["msg"] = "驗證碼錯誤!" return JsonResponse(response) return render(request,"login.html") def get_valid_code_img(request): """ 基於PIL模塊動態生成響應狀態碼圖片; :param request: :return: """ from blog.utils.validCode import get_valid_code_img data = get_valid_code_img(request) return HttpResponse(data) def index(request): return render(request,"index.html") """ 小結: 一、一次請求伴隨着屢次請求; 二、PIL模塊的掌握; 三、session存儲; 四、驗證碼刷新,基於js鼠標的click()事件進行; """
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # __Author__:TQTL911 # Version:python3.6.6 # Time:2018/8/23 21:30 import random def get_random_color(): return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) def get_valid_code_img(request): # 方式1-with open方法; # with open("lufei.jpg","rb") as f: # data = f.read() # 方式2;pip install pillow; # from PIL import Image # img = Image.new("RGB",(270,40),color=get_random_color()) # with open("validCode.png","wb") as f: # img.save(f,"png") # with open("validCode.png","rb") as f: # data = f.read() # 方式3:將數據放置於內存中,加快處理速度; # from PIL import Image # from io import BytesIO # # img = Image.new("RGB",(270,40),color=get_random_color()) # f = BytesIO() # img.save(f,"png") # data = f.getvalue() # 方式4-向圖像區域他添加噪點,和字符串; from PIL import Image, ImageDraw, ImageFont from io import BytesIO import random char = str(random.randint(0, 9)) img = Image.new("RGB", (270, 40), color=get_random_color()) draw = ImageDraw.Draw(img) kumo_font = ImageFont.truetype("static/font/BASKVILL.TTF", size=28) # 保存隨機字符串; valid_code_str = "" # 生成隨機字符串; # 方法1: for i in range(0, 5): import string random_char = ' '.join( random.sample(string.ascii_lowercase + string.ascii_uppercase, 1)) # d4}5c+/m|97e@"16]s draw.text((i * 50 + 20, 5), random_char, get_random_color(), font=kumo_font) # 保存驗證碼字符串; valid_code_str += random_char # 方法2: # for i in range(500): # random_num = str(random.randint(0,9)) # random_lowercase = chr(random.randint(95,122)) # random_uppercase = chr(random.randint(65,90)) # random_char = random.choice([random_num,random_lowercase,random_uppercase]) # draw.text((i*50+20,5),random_char,get_random_color(),font=kumo_font) # 進行畫圖; # draw.line() # draw.point() # 給圖片添加上噪點; width = 270 height = 40 for i in range(5): x1 = random.randint(0, width) x2 = random.randint(0, width) y1 = random.randint(0, height) y2 = random.randint(0, height) draw.line((x1, y1, x2, y2), fill=get_random_color()) for i in range(10): draw.point([random.randint(0, width), random.randint(0, height)], fill=get_random_color()) x = random.randint(0, width) y = random.randint(0, height) draw.arc((x, y, x + 4, y + 4), 0, 90, fill=get_random_color()) print("valid_code_str", valid_code_str) request.session["valid_code_str"] = valid_code_str ''' 一、生成隨機字符串; 二、COOKIE{"sessionid":fdsfdsfds}; 三、django-session表生成記錄; ''' f = BytesIO() img.save(f, "png") data = f.getvalue() return data
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/blog/bs/css/bootstrap.css"> </head> <body> <h3>登陸頁面</h3> <div class="container"> <div class="row"> <div class="col-md-6 col-lg-offset-3"> <form > {% csrf_token %} <div class="form-group"> <label for="user">用戶名</label> <input type="text" id="user" class="form-control"> </div> <div class="form-group"> <label for="pwd">密碼</label> <input type="password" id="pwd" class="form-control"> </div > <div class="form-group"> <label for="pwd">驗證碼</label> <div class="row"> <div class="col-md-6"> <input type="text" class="form-control" id="valid_code"> </div> <div class="col-md-6"> <img width="260" height="45" id="valid_code_img" src="/get_validCode_img/" alt=""> </div> </div> </div> <input type="button" class="btn btn-default login_btn" value="submit"><span class="error"></span> </form> </div> </div> </div> <script src="/static/blog/js/jquery-3.3.1.min.js"></script> <script> //刷新圖片驗證碼; $("#valid_code_img").click(function () { $(this)[0].src+="?" }); //登錄過驗證; $(".login_btn").click(function () { $.ajax({ url:"", type:"post", data:{ user:$("#user").val(), pwd:$("#pwd").val(), valid_code:$("#valid_code").val(), csrfmiddlewaretoken:$("[name='csrfmiddlewaretoken']").val(), }, success:function (data) { console.log(data); if (data.user){ location.href = "/index/" }else { $(".error").text(data.msg).css({"color":"red","margin-left":"10px"}); //清空錯誤消息提示,1000毫秒; setTimeout(function () { $(".error").text("") },1000) } } }) }); </script> </body> </html>
極驗官網:http://www.geetest.com/前端
"""cnblogs URL Configuration The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/2.1/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: path('', views.home, name='home') Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') Including another URLconf 1. Import the include() function: from django.urls import include, path 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ from django.contrib import admin from django.urls import path from blog import views urlpatterns = { path('admin/', admin.site.urls), path('login/', views.login), path('index/', views.index), path('get_validCode_img/', views.get_valid_code_img), path('register/', views.register), }
from django.shortcuts import render,HttpResponse,redirect # Create your views here. from django.http import JsonResponse from django.contrib import auth def login(request): """ 登陸; :param request: :return: """ if request.method == "POST": response = {"user":None,"msg":None} user = request.POST.get("user") pwd = request.POST.get("pwd") valid_code = request.POST.get("valid_code") valid_code_str = request.session.get("valid_code_str") if valid_code.upper() == valid_code_str.upper(): user = auth.authenticate(username = user,password = pwd) if user: response["user"] = user.username else: response["msg"] = "用戶名或者密碼錯誤!" else: response["msg"] = "驗證碼錯誤!" return JsonResponse(response) return render(request,"login.html") def get_valid_code_img(request): """ 基於PIL模塊動態生成響應狀態碼圖片; :param request: :return: """ from blog.utils.validCode import get_valid_code_img data = get_valid_code_img(request) return HttpResponse(data) def index(request): """ 首頁; :param request: :return: """ return render(request,"index.html") from django import forms from django.forms import widgets class UserForm(forms.Form): user = forms.CharField(max_length=32,label="用戶名",widget=widgets.TextInput(attrs={"class":"form-control"})) pwd = forms.CharField(max_length=32,label="密碼",widget=widgets.PasswordInput(attrs={"class":"form-control"})) r_pwd = forms.CharField(max_length=32,label="確認密碼",widget=widgets.PasswordInput(attrs={"class":"form-control"})) email = forms.EmailField(max_length=32,label="註冊郵箱",widget=widgets.EmailInput(attrs={"class":"form-control"})) def register(request): """ 註冊; :param request: :return: """ form = UserForm() return render(request,"register.html",{"form":form})
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>註冊頁面</title> <link rel="stylesheet" href="/static/blog/bs/css/bootstrap.css"> </head> <body> <h3>註冊頁面</h3> <div class="container"> <div class="row"> <div class="col-md-6 col-lg-offset-3"> <form > {% csrf_token %} <!--進行渲染form對象--> {% for field in form %} <div class="form-group"> <label for="user">{{ field.label }}</label> {{ field }} </div> {% endfor %} <div class="form-group"> <label for="avatar">頭像</label> <input type="file"> </div> <input type="button" class="btn btn-default login_btn" value="提交"> </form> </div> </div> </div> <script src="/static/blog/js/jquery-3.3.1.min.js"></script> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>註冊頁面</title> <link rel="stylesheet" href="/static/blog/bs/css/bootstrap.css"> <style> #avatar{ display: none; } #avatar_img{ margin-left: 20px; } </style> </head> <body> <h3>註冊頁面</h3> <div class="container"> <div class="row"> <div class="col-md-6 col-lg-offset-3"> <form > {% csrf_token %} <!--進行渲染form對象--> {% for field in form %} <div class="form-group"> <label for="{{ field.auto_id }}">{{ field.label }}</label> {{ field }} </div> {% endfor %} <div class="form-group"> <label for="avatar"> 頭像 <img id="avatar_img" width="60px" height="60px" src="/static/blog/img/default.png" alt=""> </label> <input type="file" id="avatar" > </div> <input type="button" class="btn btn-default login_btn" value="提交"> </form> </div> </div> </div> <script src="/static/blog/js/jquery-3.3.1.min.js"></script> </body> </html>
<script> $("#avatar").change(function () { //一、獲取用戶選中的文件對象; var file_obj = $(this)[0].files[0]; //二、獲取文件對象的路徑; var reader = new FileReader(); reader.readAsDataURL(file_obj); //三、修改img的src屬性值,src= 文件對象的路徑; reader.onload = function(){ $("#avatar_img").attr("src",reader.result) }; }) </script>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>註冊頁面</title> <link rel="stylesheet" href="/static/blog/bs/css/bootstrap.css"> <style> #avatar{ display: none; } #avatar_img{ margin-left: 20px; } </style> </head> <body> <h3>註冊頁面</h3> <div class="container"> <div class="row"> <div class="col-md-6 col-lg-offset-3"> <form > {% csrf_token %} <!--進行渲染form對象--> {% for field in form %} <div class="form-group"> <label for="{{ field.auto_id }}">{{ field.label }}</label> {{ field }} </div> {% endfor %} <div class="form-group"> <label for="avatar"> 頭像 <img id="avatar_img" width="60px" height="60px" src="/static/blog/img/default.png" alt=""> </label> <input type="file" id="avatar" > </div> <input type="button" class="btn btn-default reg_btn" value="提交"> </form> </div> </div> </div> <script src="/static/blog/js/jquery-3.3.1.min.js"></script> <!--編寫js代碼--> <script> $("#avatar").change(function () { //一、獲取用戶選中的文件對象; var file_obj = $(this)[0].files[0]; //二、獲取文件對象的路徑; var reader = new FileReader(); reader.readAsDataURL(file_obj); //三、修改img的src屬性值,src= 文件對象的路徑; reader.onload = function(){ $("#avatar_img").attr("src",reader.result) }; }); //基於Ajax提交事件; $(".reg_btn").click(function () { var formdata = new FormData(); formdata.append("user",$("#id_user").val()); formdata.append("pwd",$("#id_pwd").val()); formdata.append("r_pwd",$("#id_r_pwd").val()); formdata.append("email",$("#id_email").val()); formdata.append("avatar",$("#avatar")[0].files[0]); formdata.append("csrfmiddlewaretoken",$("[name = 'csrfmiddlewaretoken']").val()); $.ajax({ url:"", type:"post", contentType:false, processData:false, data:formdata, success:function (data) { console.log(data) } }) }) </script> </body> </html>
from django.shortcuts import render,HttpResponse,redirect # Create your views here. from django.http import JsonResponse from django.contrib import auth def login(request): """ 登陸; :param request: :return: """ if request.method == "POST": response = {"user":None,"msg":None} user = request.POST.get("user") pwd = request.POST.get("pwd") valid_code = request.POST.get("valid_code") valid_code_str = request.session.get("valid_code_str") if valid_code.upper() == valid_code_str.upper(): user = auth.authenticate(username = user,password = pwd) if user: response["user"] = user.username else: response["msg"] = "用戶名或者密碼錯誤!" else: response["msg"] = "驗證碼錯誤!" return JsonResponse(response) return render(request,"login.html") def get_valid_code_img(request): """ 基於PIL模塊動態生成響應狀態碼圖片; :param request: :return: """ from blog.utils.validCode import get_valid_code_img data = get_valid_code_img(request) return HttpResponse(data) def index(request): """ 首頁; :param request: :return: """ return render(request,"index.html") from django import forms from django.forms import widgets from django.http import JsonResponse class UserForm(forms.Form): user = forms.CharField(max_length=32,label="用戶名",widget=widgets.TextInput(attrs={"class":"form-control"})) pwd = forms.CharField(max_length=32,label="密碼",widget=widgets.PasswordInput(attrs={"class":"form-control"})) r_pwd = forms.CharField(max_length=32,label="確認密碼",widget=widgets.PasswordInput(attrs={"class":"form-control"})) email = forms.EmailField(max_length=32,label="註冊郵箱",widget=widgets.EmailInput(attrs={"class":"form-control"})) def register(request): """ 註冊; :param request: :return: """ #if request.method == "POST": if request.is_ajax(): print(request.POST) form = UserForm(request.POST) response = {"user":None,"msg":None} if form.is_valid(): response["user"] = form.cleaned_data.get("user") else: print(form.cleaned_data) print(form.errors) response["msg"] = form.errors return JsonResponse(response) form = UserForm() return render(request,"register.html",{"form":form})
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>註冊頁面</title> <link rel="stylesheet" href="/static/blog/bs/css/bootstrap.css"> <style> #avatar{ display: none; } #avatar_img{ margin-left: 20px; } </style> </head> <body> <h3>註冊頁面</h3> <div class="container"> <div class="row"> <div class="col-md-6 col-lg-offset-3"> <form id="form"> {% csrf_token %} <!--進行渲染form對象--> {% for field in form %} <div class="form-group"> <label for="{{ field.auto_id }}">{{ field.label }}</label> {{ field }} </div> {% endfor %} <div class="form-group"> <label for="avatar"> 頭像 <img id="avatar_img" width="60px" height="60px" src="/static/blog/img/default.png" alt=""> </label> <input type="file" id="avatar" > </div> <input type="button" class="btn btn-default reg_btn" value="提交"> </form> </div> </div> </div> <script src="/static/blog/js/jquery-3.3.1.min.js"></script> <!--編寫js代碼--> <script> $("#avatar").change(function () { //一、獲取用戶選中的文件對象; var file_obj = $(this)[0].files[0]; //二、獲取文件對象的路徑; var reader = new FileReader(); reader.readAsDataURL(file_obj); //三、修改img的src屬性值,src= 文件對象的路徑; reader.onload = function(){ $("#avatar_img").attr("src",reader.result) }; }); //基於Ajax提交事件; $(".reg_btn").click(function () { var formdata = new FormData(); console.log($("#form").serializeArray()); var request_data = $("#form").serializeArray(); $.each(request_data,function (index,data) { formdata.append(data.name,data.value) }); formdata.append("avatar",$("#avatar")[0].files[0]); /* var formdata = new FormData(); formdata.append("user",$("#id_user").val()); formdata.append("pwd",$("#id_pwd").val()); formdata.append("r_pwd",$("#id_r_pwd").val()); formdata.append("email",$("#id_email").val()); formdata.append("avatar",$("#avatar")[0].files[0]); formdata.append("csrfmiddlewaretoken",$("[name = 'csrfmiddlewaretoken']").val());*/ $.ajax({ url:"", type:"post", contentType:false, processData:false, data:formdata, success:function (data) { console.log(data) } }) }) </script> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>註冊頁面</title> <link rel="stylesheet" href="/static/blog/bs/css/bootstrap.css"> <style> #avatar{ display: none; } #avatar_img{ margin-left: 20px; } .error{ color: red; } </style> </head> <body> <h3>註冊頁面</h3> <div class="container"> <div class="row"> <div class="col-md-6 col-lg-offset-3"> <form id="form"> {% csrf_token %} <!--進行渲染form對象--> {% for field in form %} <div class="form-group"> <label for="{{ field.auto_id }}">{{ field.label }}</label> {{ field }}<span class="error pull-right"></span> </div> {% endfor %} <div class="form-group"> <label for="avatar"> 頭像 <img id="avatar_img" width="60px" height="60px" src="/static/blog/img/default.png" alt=""> </label> <input type="file" id="avatar" name="avatar"> </div> <input type="button" class="btn btn-default reg_btn" value="提交"> </form> </div> </div> </div> <script src="/static/blog/js/jquery-3.3.1.min.js"></script> <!--編寫js代碼--> <script> $("#avatar").change(function () { //一、獲取用戶選中的文件對象; var file_obj = $(this)[0].files[0]; //二、獲取文件對象的路徑; var reader = new FileReader(); reader.readAsDataURL(file_obj); //三、修改img的src屬性值,src= 文件對象的路徑; reader.onload = function(){ $("#avatar_img").attr("src",reader.result) }; }); //基於Ajax提交事件; $(".reg_btn").click(function () { var formdata = new FormData(); console.log($("#form").serializeArray()); var request_data = $("#form").serializeArray(); $.each(request_data,function (index,data) { formdata.append(data.name,data.value) }); formdata.append("avatar",$("#avatar")[0].files[0]); /* var formdata = new FormData(); formdata.append("user",$("#id_user").val()); formdata.append("pwd",$("#id_pwd").val()); formdata.append("r_pwd",$("#id_r_pwd").val()); formdata.append("email",$("#id_email").val()); formdata.append("avatar",$("#avatar")[0].files[0]); formdata.append("csrfmiddlewaretoken",$("[name = 'csrfmiddlewaretoken']").val());*/ $.ajax({ url:"", type:"post", contentType:false, processData:false, data:formdata, success:function (data) { console.log(data); if(data.user){ //註冊成功; }else { //console.log(data.msg) $.each(data.msg,function (field,error_list) { console.log(field,error_list); $("#id_"+field).next().html(error_list[0]) }) } } }); }); </script> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>註冊頁面</title> <link rel="stylesheet" href="/static/blog/bs/css/bootstrap.css"> <style> #avatar{ display: none; } #avatar_img{ margin-left: 20px; } .error{ color: red; } </style> </head> <body> <h3>註冊頁面</h3> <div class="container"> <div class="row"> <div class="col-md-6 col-lg-offset-3"> <form id="form"> {% csrf_token %} <!--進行渲染form對象--> {% for field in form %} <div class="form-group"> <label for="{{ field.auto_id }}">{{ field.label }}</label> {{ field }}<span class="error pull-right"></span> </div> {% endfor %} <div class="form-group"> <label for="avatar"> 頭像 <img id="avatar_img" width="60px" height="60px" src="/static/blog/img/default.png" alt=""> </label> <input type="file" id="avatar" name="avatar"> </div> <input type="button" class="btn btn-default reg_btn" value="提交"> </form> </div> </div> </div> <script src="/static/blog/js/jquery-3.3.1.min.js"></script> <!--編寫js代碼--> <script> $("#avatar").change(function () { //一、獲取用戶選中的文件對象; var file_obj = $(this)[0].files[0]; //二、獲取文件對象的路徑; var reader = new FileReader(); reader.readAsDataURL(file_obj); //三、修改img的src屬性值,src= 文件對象的路徑; reader.onload = function(){ $("#avatar_img").attr("src",reader.result) }; }); //基於Ajax提交事件; $(".reg_btn").click(function () { var formdata = new FormData(); console.log($("#form").serializeArray()); var request_data = $("#form").serializeArray(); $.each(request_data,function (index,data) { formdata.append(data.name,data.value) }); formdata.append("avatar",$("#avatar")[0].files[0]); /* var formdata = new FormData(); formdata.append("user",$("#id_user").val()); formdata.append("pwd",$("#id_pwd").val()); formdata.append("r_pwd",$("#id_r_pwd").val()); formdata.append("email",$("#id_email").val()); formdata.append("avatar",$("#avatar")[0].files[0]); formdata.append("csrfmiddlewaretoken",$("[name = 'csrfmiddlewaretoken']").val());*/ $.ajax({ url:"", type:"post", contentType:false, processData:false, data:formdata, success:function (data) { console.log(data); if(data.user){ //註冊成功; }else {//註冊失敗 //console.log(data.msg) //清空錯誤提示消息; $("span.error").html(); $(".form-group").removeClass("has-error"); //展現這次提提交的信息; $.each(data.msg,function (field,error_list) { console.log(field,error_list); $("#id_"+field).next().html(error_list[0]); $("#id_"+field).parent().addClass("has-error"); }) } } }); }); </script> </body> </html>
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# __Author__:TQTL911
# Version:python3.6.6
# Time:2018/8/24 14:41
from django import forms
from django.forms import widgets
from django.http import JsonResponse
from blog.models import UserInfo
from django.core.exceptions import NON_FIELD_ERRORS, ValidationError
class UserForm(forms.Form):
user = forms.CharField(max_length=32,error_messages={"required":"該字段不能爲空!"},label="用戶名",widget=widgets.TextInput(attrs={"class":"form-control"}))
pwd = forms.CharField(max_length=32,label="密碼",widget=widgets.PasswordInput(attrs={"class":"form-control"}))
r_pwd = forms.CharField(max_length=32,label="確認密碼",widget=widgets.PasswordInput(attrs={"class":"form-control"}))
email = forms.EmailField(max_length=32,label="註冊郵箱",widget=widgets.EmailInput(attrs={"class":"form-control"}))
def clean_user(self):
user = self.cleaned_data.get("user")
user = UserInfo.objects.filter(username=user).first()
if not user:
return user
else:
raise ValidationError("該用戶已經註冊")
def clean(self):
pwd = self.cleaned_data.get("pwd")
r_pwd = self.cleaned_data.get("r_pwd")
if pwd == r_pwd:
return self.cleaned_data
else:
raise ValidationError("兩次密碼不一致!")
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>註冊頁面</title> <link rel="stylesheet" href="/static/blog/bs/css/bootstrap.css"> <style> #avatar{ display: none; } #avatar_img{ margin-left: 20px; } .error{ color: red; } </style> </head> <body> <h3>註冊頁面</h3> <div class="container"> <div class="row"> <div class="col-md-6 col-lg-offset-3"> <form id="form"> {% csrf_token %} <!--進行渲染form對象--> {% for field in form %} <div class="form-group"> <label for="{{ field.auto_id }}">{{ field.label }}</label> {{ field }}<span class="error pull-right"></span> </div> {% endfor %} <div class="form-group"> <label for="avatar"> 頭像 <img id="avatar_img" width="60px" height="60px" src="/static/blog/img/default.png" alt=""> </label> <input type="file" id="avatar" name="avatar"> </div> <input type="button" class="btn btn-default reg_btn" value="提交"> </form> </div> </div> </div> <script src="/static/blog/js/jquery-3.3.1.min.js"></script> <!--編寫js代碼--> <script> $("#avatar").change(function () { //一、獲取用戶選中的文件對象; var file_obj = $(this)[0].files[0]; //二、獲取文件對象的路徑; var reader = new FileReader(); reader.readAsDataURL(file_obj); //三、修改img的src屬性值,src= 文件對象的路徑; reader.onload = function(){ $("#avatar_img").attr("src",reader.result) }; }); //基於Ajax提交事件; $(".reg_btn").click(function () { var formdata = new FormData(); console.log($("#form").serializeArray()); var request_data = $("#form").serializeArray(); $.each(request_data,function (index,data) { formdata.append(data.name,data.value) }); formdata.append("avatar",$("#avatar")[0].files[0]); /* var formdata = new FormData(); formdata.append("user",$("#id_user").val()); formdata.append("pwd",$("#id_pwd").val()); formdata.append("r_pwd",$("#id_r_pwd").val()); formdata.append("email",$("#id_email").val()); formdata.append("avatar",$("#avatar")[0].files[0]); formdata.append("csrfmiddlewaretoken",$("[name = 'csrfmiddlewaretoken']").val());*/ $.ajax({ url:"", type:"post", contentType:false, processData:false, data:formdata, success:function (data) { console.log(data); if(data.user){ //註冊成功; }else {//註冊失敗 //console.log(data.msg) //清空錯誤提示消息; $("span.error").html(); $(".form-group").removeClass("has-error"); //展現這次提提交的信息; $.each(data.msg,function (field,error_list) { console.log(field,error_list); if(field=="__all__"){ $("#id_r_pwd").next().html(error_list[0]).parent().addClass("has-error") } $("#id_"+field).next().html(error_list[0]); $("#id_"+field).parent().addClass("has-error"); }) } } }); }); </script> </body> </html>
from django.shortcuts import render,HttpResponse,redirect # Create your views here. from django.http import JsonResponse from django.contrib import auth def login(request): """ 登陸; :param request: :return: """ if request.method == "POST": response = {"user":None,"msg":None} user = request.POST.get("user") pwd = request.POST.get("pwd") valid_code = request.POST.get("valid_code") valid_code_str = request.session.get("valid_code_str") if valid_code.upper() == valid_code_str.upper(): user = auth.authenticate(username = user,password = pwd) if user: response["user"] = user.username else: response["msg"] = "用戶名或者密碼錯誤!" else: response["msg"] = "驗證碼錯誤!" return JsonResponse(response) return render(request,"login.html") def get_valid_code_img(request): """ 基於PIL模塊動態生成響應狀態碼圖片; :param request: :return: """ from blog.utils.validCode import get_valid_code_img data = get_valid_code_img(request) return HttpResponse(data) def index(request): """ 首頁; :param request: :return: """ return render(request,"index.html") from blog.Myforms import UserForm from blog.models import UserInfo def register(request): """ 註冊; :param request: :return: """ #if request.method == "POST": if request.is_ajax(): print(request.POST) form = UserForm(request.POST) response = {"user":None,"msg":None} if form.is_valid(): response["user"] = form.cleaned_data.get("user") #生成一條用戶記錄; user = form.cleaned_data.get("user") pwd = form.cleaned_data.get("pwd") email = form.cleaned_data.get("email") avatar_obj = request.FILES.get("avatar") if avatar_obj: user_obj = UserInfo.objects.create_user(username=user,password=pwd,email=email,avatar = avatar_obj ) else: user_obj = UserInfo.objects.create_user(username=user, password=pwd, email=email) else: print(form.cleaned_data) print(form.errors) response["msg"] = form.errors return JsonResponse(response) form = UserForm() return render(request,"register.html",{"form":form})
from django.shortcuts import render, HttpResponse, redirect # Create your views here. from django.http import JsonResponse from django.contrib import auth from blog.Myforms import UserForm from blog.models import UserInfo def login(request): """ 登陸; :param request: :return: """ if request.method == "POST": response = {"user": None, "msg": None} user = request.POST.get("user") pwd = request.POST.get("pwd") valid_code = request.POST.get("valid_code") valid_code_str = request.session.get("valid_code_str") if valid_code.upper() == valid_code_str.upper(): user = auth.authenticate(username=user, password=pwd) if user: response["user"] = user.username else: response["msg"] = "用戶名或者密碼錯誤!" else: response["msg"] = "驗證碼錯誤!" return JsonResponse(response) return render(request, "login.html") def get_valid_code_img(request): """ 基於PIL模塊動態生成響應狀態碼圖片; :param request: :return: """ from blog.utils.validCode import get_valid_code_img data = get_valid_code_img(request) return HttpResponse(data) def index(request): """ 首頁; :param request: :return: """ return render(request, "index.html") def register(request): """ 註冊; :param request: :return: """ # if request.method == "POST": if request.is_ajax(): # print(request.POST) form = UserForm(request.POST) response = {"user": None, "msg": None} if form.is_valid(): response["user"] = form.cleaned_data.get("user") # 生成一條用戶記錄; user = form.cleaned_data.get("user") pwd = form.cleaned_data.get("pwd") email = form.cleaned_data.get("email") avatar_obj = request.FILES.get("avatar") ''' if avatar_obj: user_obj = UserInfo.objects.create_user(username=user,password=pwd,email=email,avatar = avatar_obj ) else: user_obj = UserInfo.objects.create_user(username=user, password=pwd, email=email) ''' extra = {} if avatar_obj: extra["avatar"] = avatar_obj UserInfo.objects.create_user(username=user, password=pwd, email=email, ) else: # print(form.cleaned_data) # print(form.errors) response["msg"] = form.errors return JsonResponse(response) form = UserForm() return render(request, "register.html", {"form": form})
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>博客系統首頁</title> <link rel="stylesheet" href="/static/blog/bs/css/bootstrap.css"> <script src="/static/blog/js/jquery-3.3.1.min.js"></script> <script src="/static/blog/bs/js/bootstrap.min.js"></script> <style> #user_icon { font-size: 18px; margin-right: 10px; vertical-align: -3px; } </style> </head> <body> <nav class="navbar navbar-default"> <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="#">隨筆 <span class="sr-only">(current)</span></a></li> <li><a href="#">新聞</a></li> <li><a href="#">博文</a></li> </ul> <ul class="nav navbar-nav navbar-right"> {% if request.user.is_authenticated %} <li><a href="#"><span id="user_icon" class="glyphicon glyphicon-user"></span>{{ 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><a href="/logout/">註銷</a></li> <li role="separator" class="divider"></li> <li><a href="#">Separated link</a></li> </ul> </li> {% else %} <li><a href="/login/">登陸</a></li> <li><a href="/register/">註冊</a></li> {% endif %} </ul> </div><!-- /.navbar-collapse --> </div><!-- /.container-fluid --> </nav> </body> </html>
from django.shortcuts import render, HttpResponse, redirect # Create your views here. from django.http import JsonResponse from django.contrib import auth from blog.Myforms import UserForm from blog.models import UserInfo def login(request): """ 登陸; :param request: :return: """ if request.method == "POST": response = {"user": None, "msg": None} user = request.POST.get("user") pwd = request.POST.get("pwd") valid_code = request.POST.get("valid_code") valid_code_str = request.session.get("valid_code_str") if valid_code.upper() == valid_code_str.upper(): user = auth.authenticate(username=user, password=pwd) if user: auth.login(request, user) response["user"] = user.username else: response["msg"] = "用戶名或者密碼錯誤!" else: response["msg"] = "驗證碼錯誤!" return JsonResponse(response) return render(request, "login.html") def index(request): """ 首頁; :param request: :return: """ return render(request, "index.html") def logout(request): auth.logout(request) # 等同於request.session.flush() return redirect("/login/") def get_valid_code_img(request): """ 基於PIL模塊動態生成響應狀態碼圖片; :param request: :return: """ from blog.utils.validCode import get_valid_code_img data = get_valid_code_img(request) return HttpResponse(data) def register(request): """ 註冊; :param request: :return: """ # if request.method == "POST": if request.is_ajax(): # print(request.POST) form = UserForm(request.POST) response = {"user": None, "msg": None} if form.is_valid(): response["user"] = form.cleaned_data.get("user") # 生成一條用戶記錄; user = form.cleaned_data.get("user") pwd = form.cleaned_data.get("pwd") email = form.cleaned_data.get("email") avatar_obj = request.FILES.get("avatar") ''' if avatar_obj: user_obj = UserInfo.objects.create_user(username=user,password=pwd,email=email,avatar = avatar_obj ) else: user_obj = UserInfo.objects.create_user(username=user, password=pwd, email=email) ''' extra = {} if avatar_obj: extra["avatar"] = avatar_obj UserInfo.objects.create_user(username=user, password=pwd, email=email, **extra) else: # print(form.cleaned_data) # print(form.errors) response["msg"] = form.errors return JsonResponse(response) form = UserForm() return render(request, "register.html", {"form": form})
"""cnblogs URL Configuration The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/2.1/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: path('', views.home, name='home') Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') Including another URLconf 1. Import the include() function: from django.urls import include, path 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ from django.contrib import admin from django.urls import path, re_path from blog import views from django.views.static import serve from cnblogs import settings urlpatterns = [ path('admin/', admin.site.urls), path('login/', views.login), path('index/', views.index), path('logout/', views.logout), re_path('^$', views.index), path('get_validCode_img/', views.get_valid_code_img), path('register/', views.register), # media配置; re_path(r"media/(?P<path>.*)$", serve, {"document_root": settings.MEDIA_ROOT}), ]
<!--引入BootStrap格柵系統--> <div class="container-fluid"> <div class="row"> <div class="col-md-3"> <div class="panel panel-warning"> <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-danger"> <div class="panel-heading">Panel heading without title</div> <div class="panel-body"> Panel content </div> </div> </div> <div class="col-md-6">222</div> <div class="col-md-3"> <div class="panel panel-default"> <div class="panel-heading">Panel heading without title</div> <div class="panel-body"> Panel content </div> </div> <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-default"> <div class="panel-heading">Panel heading without title</div> <div class="panel-body"> Panel content </div> </div> </div> </div> </div>
from django.contrib import admin # Register your models here. from blog import models admin.site.register(models.UserInfo) admin.site.register(models.Blog) admin.site.register(models.Category) admin.site.register(models.Tag) admin.site.register(models.Article) admin.site.register(models.ArticleUpDown) admin.site.register(models.Article2Tag) admin.site.register(models.Comment)
<div class="col-md-6"> <div class="article_list"> {% for articel in article_list %} <div class="articel-item"> <h5><a href="">{{ articel.title }}</a></h5> <div class="article-desc"> <span class="media-left"> <a href=""><img width="56" height="56" src="media/{{ articel.user.avatar }}" alt=""></a> </span> <span class="media-right"> {{ articel.desc }} </span> </div> <hr> </div> {% endfor %} </div> </div>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>博客系統首頁</title> <link rel="stylesheet" href="/static/blog/bs/css/bootstrap.css"> <script src="/static/blog/js/jquery-3.3.1.min.js"></script> <script src="/static/blog/bs/js/bootstrap.min.js"></script> <style> #user_icon { font-size: 18px; margin-right: 10px; vertical-align: -3px; } .pub_info{ margin-top: 10px; } .pub_info .glyphicon-comment{ vertical-align: -1px; } </style> </head> <body> <nav class="navbar navbar-default"> <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="#">隨筆 <span class="sr-only">(current)</span></a></li> <li><a href="#">新聞</a></li> <li><a href="#">博文</a></li> </ul> <ul class="nav navbar-nav navbar-right"> {% if request.user.is_authenticated %} <li><a href="#"><span id="user_icon" class="glyphicon glyphicon-user"></span>{{ 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><a href="/logout/">註銷</a></li> <li role="separator" class="divider"></li> <li><a href="#">Separated link</a></li> </ul> </li> {% else %} <li><a href="/login/">登陸</a></li> <li><a href="/register/">註冊</a></li> {% endif %} </ul> </div><!-- /.navbar-collapse --> </div><!-- /.container-fluid --> </nav> <!--引入BootStrap格柵系統--> <div class="container-fluid"> <div class="row"> <div class="col-md-3"> <div class="panel panel-warning"> <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-danger"> <div class="panel-heading">Panel heading without title</div> <div class="panel-body"> Panel content </div> </div> </div> <div class="col-md-6"> <div class="article_list"> {% for articel in article_list %} <div class="articel-item"> <h5><a href="">{{ articel.title }}</a></h5> <div class="article-desc"> <span class="media-left"> <a href=""><img width="56" height="56" src="media/{{ articel.user.avatar }}" alt=""></a> </span> <span class="media-right"> {{ articel.desc }} </span> </div> <hr> </div> <div class="small pub_info"> <span><a href="">{{ articel.user.username }}</a></span> <span>發佈於 {{ articel.create_time|date:"Y-m-d H:i" }}</span> <span class="glyphicon glyphicon-comment"></span>評論({{ articel.comment_count }}) <span class="glyphicon glyphicon-thumbs-up"></span>點贊({{ articel.up_count }}) </div> {% endfor %} </div> </div> <div class="col-md-3"> <div class="panel panel-default"> <div class="panel-heading">Panel heading without title</div> <div class="panel-body"> Panel content </div> </div> <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-default"> <div class="panel-heading">Panel heading without title</div> <div class="panel-body"> Panel content </div> </div> </div> </div> </div> </body> </html>
"""cnblogs URL Configuration The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/2.1/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: path('', views.home, name='home') Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') Including another URLconf 1. Import the include() function: from django.urls import include, path 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ from django.contrib import admin from django.urls import path, re_path from blog import views from django.views.static import serve from cnblogs import settings urlpatterns = [ path('admin/', admin.site.urls), path('login/', views.login), path('index/', views.index), path('logout/', views.logout), re_path('^$', views.index), path('get_validCode_img/', views.get_valid_code_img), path('register/', views.register), # media配置; re_path(r'media/(?P<path>.*)$', serve, {"document_root": settings.MEDIA_ROOT}), # 我的站點URL; re_path(r'^(?P<username>\w+)$', views.home_site), ]
from django.shortcuts import render, HttpResponse, redirect # Create your views here. from django.http import JsonResponse from django.contrib import auth from blog.Myforms import UserForm from blog.models import UserInfo from blog import models def login(request): """ 登陸; :param request: :return: """ if request.method == "POST": response = {"user": None, "msg": None} user = request.POST.get("user") pwd = request.POST.get("pwd") valid_code = request.POST.get("valid_code") valid_code_str = request.session.get("valid_code_str") if valid_code.upper() == valid_code_str.upper(): user = auth.authenticate(username=user, password=pwd) if user: auth.login(request, user) response["user"] = user.username else: response["msg"] = "用戶名或者密碼錯誤!" else: response["msg"] = "驗證碼錯誤!" return JsonResponse(response) return render(request, "login.html") def index(request): """ 首頁; :param request: :return: """ article_list = models.Article.objects.all() return render(request, "index.html", {"article_list": article_list}) def logout(request): auth.logout(request) # 等同於request.session.flush() return redirect("/login/") def get_valid_code_img(request): """ 基於PIL模塊動態生成響應狀態碼圖片; :param request: :return: """ from blog.utils.validCode import get_valid_code_img data = get_valid_code_img(request) return HttpResponse(data) def register(request): """ 註冊; :param request: :return: """ # if request.method == "POST": if request.is_ajax(): # print(request.POST) form = UserForm(request.POST) response = {"user": None, "msg": None} if form.is_valid(): response["user"] = form.cleaned_data.get("user") # 生成一條用戶記錄; user = form.cleaned_data.get("user") pwd = form.cleaned_data.get("pwd") email = form.cleaned_data.get("email") avatar_obj = request.FILES.get("avatar") ''' if avatar_obj: user_obj = UserInfo.objects.create_user(username=user,password=pwd,email=email,avatar = avatar_obj ) else: user_obj = UserInfo.objects.create_user(username=user, password=pwd, email=email) ''' extra = {} if avatar_obj: extra["avatar"] = avatar_obj UserInfo.objects.create_user(username=user, password=pwd, email=email, **extra) else: # print(form.cleaned_data) # print(form.errors) response["msg"] = form.errors return JsonResponse(response) form = UserForm() return render(request, "register.html", {"form": form}) def home_site(request, username): """ 我的站點視圖函數; :param request: :return: """ print("username", username) user = UserInfo.objects.filter(username=username).first() # 判斷用戶是否存在; if not user: return render(request, "not_found.html") # 查詢當前站點對象: blog = user.blog # 當前用戶或者當前站點對應的全部文章; # 基於對象查詢; # article_list = user.article_set.all() # 基於雙下劃線的查詢; article_list = models.Article.objects.filter(user=user) return render(request, "home_site.html")
def home_site(request, username): """ 我的站點視圖函數; :param request: :return: """ print("username", username) user = UserInfo.objects.filter(username=username).first() # 判斷用戶是否存在; if not user: return render(request, "not_found.html") # 查詢當前站點對象: blog = user.blog # 當前用戶或者當前站點對應的全部文章; # 基於對象查詢; # article_list = user.article_set.all() # 基於雙下劃線的查詢; article_list = models.Article.objects.filter(user=user) # 每個後表的模型.objedts.values("pk").annotate(聚合函數(關聯表__統計字段)).values("表模型的全部字段以及統計字段") # 一、查詢每個分類名稱以及對應的文章數; ret = models.Category.objects.values("pk").annotate(c=Count("article__title")).values("title", "c") print(ret) # 二、查詢當前站點的每個分類名稱以及對應的文章數; cate_list = models.Category.objects.filter(blog=blog).values("pk").annotate(c=Count("article__title")).values_list( "title", "c") print(cate_list) # 三、查詢當前站點的每個標籤名稱對應的文章數; tag_list = models.Tag.objects.filter(blog=blog).values("pk").annotate(c=Count("article")).values_list("title", "c") print(tag_list) return render(request, "home_site.html")
from django.shortcuts import render, HttpResponse, redirect # Create your views here. from django.http import JsonResponse from django.contrib import auth from blog.Myforms import UserForm from blog.models import UserInfo from blog import models from django.db.models import Count def login(request): """ 登陸; :param request: :return: """ if request.method == "POST": response = {"user": None, "msg": None} user = request.POST.get("user") pwd = request.POST.get("pwd") valid_code = request.POST.get("valid_code") valid_code_str = request.session.get("valid_code_str") if valid_code.upper() == valid_code_str.upper(): user = auth.authenticate(username=user, password=pwd) if user: auth.login(request, user) response["user"] = user.username else: response["msg"] = "用戶名或者密碼錯誤!" else: response["msg"] = "驗證碼錯誤!" return JsonResponse(response) return render(request, "login.html") def index(request): """ 首頁; :param request: :return: """ article_list = models.Article.objects.all() return render(request, "index.html", {"article_list": article_list}) def logout(request): auth.logout(request) # 等同於request.session.flush() return redirect("/login/") def get_valid_code_img(request): """ 基於PIL模塊動態生成響應狀態碼圖片; :param request: :return: """ from blog.utils.validCode import get_valid_code_img data = get_valid_code_img(request) return HttpResponse(data) def register(request): """ 註冊; :param request: :return: """ # if request.method == "POST": if request.is_ajax(): # print(request.POST) form = UserForm(request.POST) response = {"user": None, "msg": None} if form.is_valid(): response["user"] = form.cleaned_data.get("user") # 生成一條用戶記錄; user = form.cleaned_data.get("user") pwd = form.cleaned_data.get("pwd") email = form.cleaned_data.get("email") avatar_obj = request.FILES.get("avatar") ''' if avatar_obj: user_obj = UserInfo.objects.create_user(username=user,password=pwd,email=email,avatar = avatar_obj ) else: user_obj = UserInfo.objects.create_user(username=user, password=pwd, email=email) ''' extra = {} if avatar_obj: extra["avatar"] = avatar_obj UserInfo.objects.create_user(username=user, password=pwd, email=email, **extra) else: # print(form.cleaned_data) # print(form.errors) response["msg"] = form.errors return JsonResponse(response) form = UserForm() return render(request, "register.html", {"form": form}) def home_site(request, username): """ 我的站點視圖函數; :param request: :return: """ print("username", username) user = UserInfo.objects.filter(username=username).first() # 判斷用戶是否存在; if not user: return render(request, "not_found.html") # 查詢當前站點對象: blog = user.blog # 當前用戶或者當前站點對應的全部文章; # 基於對象查詢; # article_list = user.article_set.all() # 基於雙下劃線的查詢; article_list = models.Article.objects.filter(user=user) # 每個後表的模型.objedts.values("pk").annotate(聚合函數(關聯表__統計字段)).values("表模型的全部字段以及統計字段") # 一、查詢每個分類名稱以及對應的文章數; ret1 = models.Category.objects.values("pk").annotate(c=Count("article__title")).values("title", "c") print(ret1) # 二、查詢當前站點的每個分類名稱以及對應的文章數; cate_list = models.Category.objects.filter(blog=blog).values("pk").annotate(c=Count("article__title")).values_list( "title", "c") print(cate_list) # 三、查詢當前站點的每個標籤名稱對應的文章數; tag_list = models.Tag.objects.filter(blog=blog).values("pk").annotate(c=Count("article")).values_list("title", "c") print(tag_list) #四、查詢當前站點每個年月的名稱以及對應的文章數之extra函數; ret2 = models.Article.objects.extra(select={"is_recent":"create_time > '2018-08-26'"}).values("title","is_recent") print(ret2) ret3 = models.Article.objects.extra(select={"y_m_d_date":"date_format(create_time,'%%Y-%%m-%%d')"}).values("title","y_m_d_date") print("這裏是ret3",ret3) return render(request, "home_site.html")
date_list = models.Article.objects.filter(user=user).extra(select={"y_m_date":"date_format(create_time,'%%Y-%%m')"}).values("y_m_date").annotate(c = Count("nid")).values("y_m_date","c") print("這裏是date_list",date_list)
from django.shortcuts import render, HttpResponse, redirect # Create your views here. from django.http import JsonResponse from django.contrib import auth from blog.Myforms import UserForm from blog.models import UserInfo from blog import models from django.db.models import Count def login(request): """ 登陸; :param request: :return: """ if request.method == "POST": response = {"user": None, "msg": None} user = request.POST.get("user") pwd = request.POST.get("pwd") valid_code = request.POST.get("valid_code") valid_code_str = request.session.get("valid_code_str") if valid_code.upper() == valid_code_str.upper(): user = auth.authenticate(username=user, password=pwd) if user: auth.login(request, user) response["user"] = user.username else: response["msg"] = "用戶名或者密碼錯誤!" else: response["msg"] = "驗證碼錯誤!" return JsonResponse(response) return render(request, "login.html") def index(request): """ 首頁; :param request: :return: """ article_list = models.Article.objects.all() return render(request, "index.html", {"article_list": article_list}) def logout(request): auth.logout(request) # 等同於request.session.flush() return redirect("/login/") def get_valid_code_img(request): """ 基於PIL模塊動態生成響應狀態碼圖片; :param request: :return: """ from blog.utils.validCode import get_valid_code_img data = get_valid_code_img(request) return HttpResponse(data) def register(request): """ 註冊; :param request: :return: """ # if request.method == "POST": if request.is_ajax(): # print(request.POST) form = UserForm(request.POST) response = {"user": None, "msg": None} if form.is_valid(): response["user"] = form.cleaned_data.get("user") # 生成一條用戶記錄; user = form.cleaned_data.get("user") pwd = form.cleaned_data.get("pwd") email = form.cleaned_data.get("email") avatar_obj = request.FILES.get("avatar") ''' if avatar_obj: user_obj = UserInfo.objects.create_user(username=user,password=pwd,email=email,avatar = avatar_obj ) else: user_obj = UserInfo.objects.create_user(username=user, password=pwd, email=email) ''' extra = {} if avatar_obj: extra["avatar"] = avatar_obj UserInfo.objects.create_user(username=user, password=pwd, email=email, **extra) else: # print(form.cleaned_data) # print(form.errors) response["msg"] = form.errors return JsonResponse(response) form = UserForm() return render(request, "register.html", {"form": form}) def home_site(request, username): """ 我的站點視圖函數; :param request: :return: """ print("username", username) user = UserInfo.objects.filter(username=username).first() # 判斷用戶是否存在; if not user: return render(request, "not_found.html") # 查詢當前站點對象: blog = user.blog # 當前用戶或者當前站點對應的全部文章; # 基於對象查詢; # article_list = user.article_set.all() # 基於雙下劃線的查詢; article_list = models.Article.objects.filter(user=user) # 每個後表的模型.objedts.values("pk").annotate(聚合函數(關聯表__統計字段)).values("表模型的全部字段以及統計字段") # 一、查詢每個分類名稱以及對應的文章數; ret1 = models.Category.objects.values("pk").annotate(c=Count("article__title")).values("title", "c") print(ret1) # 二、查詢當前站點的每個分類名稱以及對應的文章數; cate_list = models.Category.objects.filter(blog=blog).values("pk").annotate(c=Count("article__title")).values_list( "title", "c") print(cate_list) # 三、查詢當前站點的每個標籤名稱對應的文章數; """ 方式1: tag_list = models.Tag.objects.filter(blog=blog).values("pk").annotate(c=Count("article")).values_list("title", "c") print(tag_list) #四、查詢當前站點每個年月的名稱以及對應的文章數之extra函數; ret2 = models.Article.objects.extra(select={"is_recent":"create_time > '2018-08-26'"}).values("title","is_recent") print(ret2) date_list = models.Article.objects.filter(user=user).extra(select={"y_m_date":"date_format(create_time,'%%Y-%%m')"}).values("y_m_date").annotate(c = Count("nid")).values("y_m_date","c") print("這裏是date_list",date_list) """ """ 方式2: """ from django.db.models.functions import TruncMonth ret4 = models.Article.objects.filter(user=user).annotate(month = TruncMonth("Create_time")).values("month").annotate(c= Count("nid")).values_list("month","c") print("ret----->",ret4) return render(request, "home_site.html")
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>home_site</title> <style type="text/css"> * { margin: 0; padding: 0; } .header { width: 100%; height: 60px; background-color: #369; } .header .title { font-size: 18px; font-weight: 100; line-height: 60px; color: white; margin-left: 15px; margin-top: -10px; } .backend{ float: right; color: white; text-decoration: none; font-size: 14px; margin-right: 10px; margin-top: 10px; } </style> </head> <body> <div class="header"> <div class="content"> <p class="title"> <span>{{ blog.title }}</span> <a href="" class="backend">管理</a> </p> </div> </div> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>home_site</title> <link rel="stylesheet" href="/static/blog/bs/css/bootstrap.css"> <script src="/static/blog/js/jquery-3.3.1.min.js"></script> <script src="/static/blog/bs/js/bootstrap.min.js"></script> <style type="text/css"> * { margin: 0; padding: 0; } .header { width: 100%; height: 60px; background-color: #369; } .header .title { font-size: 18px; font-weight: 100; line-height: 60px; color: white; margin-left: 15px; margin-top: -10px; } .backend { float: right; color: white; text-decoration: none; font-size: 14px; margin-right: 10px; margin-top: 10px; } .pub_info { margin-top: 10px; color: darkgray; } </style> </head> <body> <div class="header"> <div class="content"> <p class="title"> <span>{{ blog.title }}</span> <a href="" class="backend">管理</a> </p> </div> </div> <div class="container"> <div class="row"> <div class="col-md-3"> </div> <div class="col-md-9"> <div class="article_list"> {% for article in article_list %} <div class="article-item clearfix"> <h5><a href="">{{ article.title }}</a></h5> <div class="article-desc"> {{ article.desc }} </div> </div> <div class="small pub_info pull-right"> <span>發佈於 {{ article.create_time|date:"Y-m-d H:i" }}</span> <span class="glyphicon glyphicon-comment"></span>評論({{ article.comment_count }}) <span class="glyphicon glyphicon-thumbs-up"></span>點贊({{ article.up_count }}) </div> <hr> {% endfor %} </div> </div> </div> </div> </body> </html>
<div class="col-md-3"> <div class="panel panel-warning"> <div class="panel-heading">個人標籤</div> <div class="panel-body"> {% for tag in tag_list %} <p>{{ tag.0 }}({{ tag.1 }})</p> {% endfor %} </div> </div> <div class="panel panel-danger"> <div class="panel-heading">隨筆分類</div> <div class="panel-body"> {% for cate in cate_list %} <p>{{ cate.0 }}({{ cate.1 }})</p> {% endfor %} </div> </div> <div class="panel panel-success"> <div class="panel-heading">隨筆歸檔</div> <div class="panel-body"> {% for date in date_list %} <p>{{ date.0 }}({{ date.1 }})</p> {% endfor %} </div> </div> </div>
def home_site(request, username, **kwargs): """ 我的站點視圖函數 :param request: :return: """ print("kwargs", kwargs) # 區分訪問是的站點頁面仍是站點下的跳轉頁面 print("username", username) user = UserInfo.objects.filter(username=username).first() # 判斷用戶是否存在! if not user: return render(request, "not_found.html") # 查詢當前站點對象 blog = user.blog # 1 當前用戶或者當前站點對應全部文章 # 基於對象查詢 # article_list=user.article_set.all() # 基於 __ article_list = models.Article.objects.filter(user=user) if kwargs: condition = kwargs.get("condition") param = kwargs.get("param") # 2012-12 if condition == "category": article_list = article_list.filter(category__title=param) elif condition == "tag": article_list = article_list.filter(tags__title=param) else: year, month = param.split("/") article_list = article_list.filter(create_time__year=year, create_time__month=month) # 每個後的表模型.objects.values("pk").annotate(聚合函數(關聯表__統計字段)).values("表模型的全部字段以及統計字段") # 查詢每個分類名稱以及對應的文章數 # ret=models.Category.objects.values("pk").annotate(c=Count("article__title")).values("title","c") # print(ret) # 查詢當前站點的每個分類名稱以及對應的文章數 cate_list = models.Category.objects.filter(blog=blog).values("pk").annotate(c=Count("article__title")).values_list( "title", "c") print(cate_list) # 查詢當前站點的每個標籤名稱以及對應的文章數 tag_list = models.Tag.objects.filter(blog=blog).values("pk").annotate(c=Count("article")).values_list("title", "c") print(tag_list) # 查詢當前站點每個年月的名稱以及對應的文章數 # ret=models.Article.objects.extra(select={"is_recent":"create_time > '2018-09-05'"}).values("title","is_recent") # print(ret) # 方式1: date_list = models.Article.objects.filter(user=user).extra( select={"y_m_date": "date_format(create_time,'%%Y/%%m')"}).values("y_m_date").annotate( c=Count("nid")).values_list("y_m_date", "c") print(date_list) # 方式2: # from django.db.models.functions import TruncMonth # # ret=models.Article.objects.filter(user=user).annotate(month=TruncMonth("create_time")).values("month").annotate(c=Count("nid")).values_list("month","c") # print("ret----->",ret) return render(request, "home_site.html", {"username": username, "blog": blog, "article_list": article_list, "tag_list": tag_list, "cate_list": cate_list,"date_list":date_list})
"""cnblogs URL Configuration The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/2.1/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: path('', views.home, name='home') Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') Including another URLconf 1. Import the include() function: from django.urls import include, path 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ from django.contrib import admin from django.urls import path, re_path from blog import views from django.views.static import serve from cnblogs import settings urlpatterns = [ path('admin/', admin.site.urls), path('login/', views.login), path('index/', views.index), path('logout/', views.logout), re_path('^$', views.index), path('get_validCode_img/', views.get_valid_code_img), path('register/', views.register), # media配置; re_path(r'media/(?P<path>.*)$', serve, {"document_root": settings.MEDIA_ROOT}), # 我的站點URL; re_path(r'^(?P<username>\w+)/(?P<condition>tag|category|archive)/(?P<param>.*)/$', views.home_site), #re_path(r'^(?P<username>\w+)/category/.*/$', views.home_site), #re_path(r'^(?P<username>\w+)/archive/.*/$', views.home_site), re_path(r'^(?P<username>\w+)$', views.home_site), ]
"""cnblogs URL Configuration The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/2.1/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: path('', views.home, name='home') Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') Including another URLconf 1. Import the include() function: from django.urls import include, path 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ from django.contrib import admin from django.urls import path, re_path from blog import views from django.views.static import serve from cnblogs import settings urlpatterns = [ path('admin/', admin.site.urls), path('login/', views.login), path('index/', views.index), path('logout/', views.logout), re_path('^$', views.index), path('get_validCode_img/', views.get_valid_code_img), path('register/', views.register), # media配置; re_path(r'media/(?P<path>.*)$', serve, {"document_root": settings.MEDIA_ROOT}), # 我的站點下的跳轉URL;# 接受的參數,home_site(request,username,condition,param) re_path(r'^(?P<username>\w+)/(?P<condition>tag|category|archive)/(?P<param>.*)/$', views.home_site), # re_path(r'^(?P<username>\w+)/category/.*/$', views.home_site), # re_path(r'^(?P<username>\w+)/archive/.*/$', views.home_site), # 我的站點URL;#接收的參數home_site(request,username="cxz") re_path(r'^(?P<username>\w+)/$', views.home_site), ]
def home_site(request, username, **kwargs): """ 我的站點視圖函數 :param request: :return: """ print("kwargs", kwargs) # 區分訪問是的站點頁面仍是站點下的跳轉頁面; print("username", username) user = UserInfo.objects.filter(username=username).first() # 判斷用戶是否存在! if not user: return render(request, "not_found.html") # 查詢當前站點對象 blog = user.blog # 1 當前用戶或者當前站點對應全部文章 # 基於對象查詢 # article_list=user.article_set.all() # 基於 __ article_list = models.Article.objects.filter(user=user) if kwargs: condition = kwargs.get("condition") param = kwargs.get("param") # 2012-12 if condition == "category": article_list = article_list.filter(category__title=param) elif condition == "tag": article_list = article_list.filter(tags__title=param) else: year, month = param.split("/") article_list = article_list.filter(create_time__year=year, create_time__month=month) # 每個後的表模型.objects.values("pk").annotate(聚合函數(關聯表__統計字段)).values("表模型的全部字段以及統計字段") # 查詢每個分類名稱以及對應的文章數 # ret=models.Category.objects.values("pk").annotate(c=Count("article__title")).values("title","c") # print(ret) # 查詢當前站點的每個分類名稱以及對應的文章數 cate_list = models.Category.objects.filter(blog=blog).values("pk").annotate(c=Count("article__title")).values_list( "title", "c") print(cate_list) # 查詢當前站點的每個標籤名稱以及對應的文章數 tag_list = models.Tag.objects.filter(blog=blog).values("pk").annotate(c=Count("article")).values_list("title", "c") print(tag_list) # 查詢當前站點每個年月的名稱以及對應的文章數 # ret=models.Article.objects.extra(select={"is_recent":"create_time > '2018-09-05'"}).values("title","is_recent") # print(ret) # 方式1: date_list = models.Article.objects.filter(user=user).extra( select={"y_m_date": "date_format(create_time,'%%Y-%%m')"}).values("y_m_date").annotate( c=Count("nid")).values_list("y_m_date", "c") print(date_list) # 方式2: # from django.db.models.functions import TruncMonth # # ret=models.Article.objects.filter(user=user).annotate(month=TruncMonth("create_time")).values("month").annotate(c=Count("nid")).values_list("month","c") # print("ret----->",ret) return render(request, "home_site.html", {"username": username, "blog": blog, "article_list": article_list, "tag_list": tag_list, "cate_list": cate_list,"date_list":date_list})
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>home_site</title> <link rel="stylesheet" href="/static/blog/bs/css/bootstrap.css"> <script src="/static/blog/js/jquery-3.3.1.min.js"></script> <script src="/static/blog/bs/js/bootstrap.min.js"></script> <style type="text/css"> * { margin: 0; padding: 0; } .header { width: 100%; height: 60px; background-color: #369; } .header .title { font-size: 18px; font-weight: 100; line-height: 60px; color: white; margin-left: 15px; margin-top: -10px; } .backend { float: right; color: white; text-decoration: none; font-size: 14px; margin-right: 10px; margin-top: 10px; } .pub_info { margin-top: 10px; color: darkgray; } </style> </head> <body> <div class="header"> <div class="content"> <p class="title"> <span>{{ blog.title }}</span> <a href="" class="backend">管理</a> </p> </div> </div> <div class="container"> <div class="row"> <div class="col-md-3"> <div class="panel panel-warning"> <div class="panel-heading">個人標籤</div> <div class="panel-body"> {% for tag in tag_list %} <p><a href="/{{ 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 cate in cate_list %} <p><a href="/{{ username }}/category/{{ cate.0 }}"> {{ cate.0 }}({{ tag.1 }})</a></p> {% endfor %} </div> </div> <div class="panel panel-success"> <div class="panel-heading">隨筆歸檔</div> <div class="panel-body"> {% for date in date_list %} <p><a href="/{{ username }}/archive/{{ date.0 }}"> {{ date.0 }}({{ tag.1 }})</a></p> {% endfor %} </div> </div> </div> <div class="col-md-9"> <div class="article_list"> {% for article in article_list %} <div class="article-item clearfix"> <h5><a href="">{{ article.title }}</a></h5> <div class="article-desc"> {{ article.desc }} </div> </div> <div class="small pub_info pull-right"> <span>發佈於 {{ article.create_time|date:"Y-m-d H:i" }}</span> <span class="glyphicon glyphicon-comment"></span>評論({{ article.comment_count }}) <span class="glyphicon glyphicon-thumbs-up"></span>點贊({{ article.up_count }}) </div> <hr> {% endfor %} </div> </div> </div> </div> </body> </html>
from django.shortcuts import render, HttpResponse, redirect # Create your views here. from django.http import JsonResponse from django.contrib import auth from blog.Myforms import UserForm from blog.models import UserInfo from blog import models from django.db.models import Count def login(request): """ 登陸; :param request: :return: """ if request.method == "POST": response = {"user": None, "msg": None} user = request.POST.get("user") pwd = request.POST.get("pwd") valid_code = request.POST.get("valid_code") valid_code_str = request.session.get("valid_code_str") if valid_code.upper() == valid_code_str.upper(): user = auth.authenticate(username=user, password=pwd) if user: auth.login(request, user) response["user"] = user.username else: response["msg"] = "用戶名或者密碼錯誤!" else: response["msg"] = "驗證碼錯誤!" return JsonResponse(response) return render(request, "login.html") def index(request): """ 首頁; :param request: :return: """ article_list = models.Article.objects.all() return render(request, "index.html", {"article_list": article_list}) def logout(request): auth.logout(request) # 等同於request.session.flush() return redirect("/login/") def get_valid_code_img(request): """ 基於PIL模塊動態生成響應狀態碼圖片; :param request: :return: """ from blog.utils.validCode import get_valid_code_img data = get_valid_code_img(request) return HttpResponse(data) def register(request): """ 註冊; :param request: :return: """ # if request.method == "POST": if request.is_ajax(): # print(request.POST) form = UserForm(request.POST) response = {"user": None, "msg": None} if form.is_valid(): response["user"] = form.cleaned_data.get("user") # 生成一條用戶記錄; user = form.cleaned_data.get("user") pwd = form.cleaned_data.get("pwd") email = form.cleaned_data.get("email") avatar_obj = request.FILES.get("avatar") ''' if avatar_obj: user_obj = UserInfo.objects.create_user(username=user,password=pwd,email=email,avatar = avatar_obj ) else: user_obj = UserInfo.objects.create_user(username=user, password=pwd, email=email) ''' extra = {} if avatar_obj: extra["avatar"] = avatar_obj UserInfo.objects.create_user(username=user, password=pwd, email=email, **extra) else: # print(form.cleaned_data) # print(form.errors) response["msg"] = form.errors return JsonResponse(response) form = UserForm() return render(request, "register.html", {"form": form}) def home_site(request, username, **kwargs): """ 我的站點視圖函數 :param request: :return: """ print("kwargs", kwargs) # 區分訪問是的站點頁面仍是站點下的跳轉頁面; print("username", username) user = UserInfo.objects.filter(username=username).first() # 判斷用戶是否存在! if not user: return render(request, "not_found.html") # 查詢當前站點對象 blog = user.blog # 1 當前用戶或者當前站點對應全部文章 # 基於對象查詢 # article_list=user.article_set.all() # 基於 __ article_list = models.Article.objects.filter(user=user) if kwargs: condition = kwargs.get("condition") param = kwargs.get("param") # 2012-12 if condition == "category": article_list = article_list.filter(category__title=param) elif condition == "tag": article_list = article_list.filter(tags__title=param) else: year, month = param.split("-") article_list = article_list.filter(create_time__year=year, create_time__month=month) # 每個後的表模型.objects.values("pk").annotate(聚合函數(關聯表__統計字段)).values("表模型的全部字段以及統計字段") # 查詢每個分類名稱以及對應的文章數 # ret=models.Category.objects.values("pk").annotate(c=Count("article__title")).values("title","c") # print(ret) # 查詢當前站點的每個分類名稱以及對應的文章數 cate_list = models.Category.objects.filter(blog=blog).values("pk").annotate(c=Count("article__title")).values_list( "title", "c") print(cate_list) # 查詢當前站點的每個標籤名稱以及對應的文章數 tag_list = models.Tag.objects.filter(blog=blog).values("pk").annotate(c=Count("article")).values_list("title", "c") print(tag_list) # 查詢當前站點每個年月的名稱以及對應的文章數 # ret=models.Article.objects.extra(select={"is_recent":"create_time > '2018-09-05'"}).values("title","is_recent") # print(ret) # 方式1: date_list = models.Article.objects.filter(user=user).extra( select={"y_m_date": "date_format(create_time,'%%Y-%%m')"}).values("y_m_date").annotate( c=Count("nid")).values_list("y_m_date", "c") print(date_list) # 方式2: # from django.db.models.functions import TruncMonth # # ret=models.Article.objects.filter(user=user).annotate(month=TruncMonth("create_time")).values("month").annotate(c=Count("nid")).values_list("month","c") # print("ret----->",ret) return render(request, "home_site.html", {"username": username, "blog": blog, "article_list": article_list, "tag_list": tag_list, "cate_list": cate_list,"date_list":date_list}) # def get_classification_data(username): # user = UserInfo.objects.filter(username=username).first() # blog = user.blog # cate_list = models.Category.objects.filter(blog=blog).values("pk").annotate(c=Count("article__title")).values_list( # "title", "c") # tag_list = models.Tag.objects.filter(blog=blog).values("pk").annotate(c=Count("article")).values_list("title", "c") # date_list = models.Article.objects.filter(user=user).extra( # select={"y_m_date": "date_format(create_time,'%%y/%%m')"} # ).values("y_m_date").annotate(c=Count("nid")).values_list("y_m_date", "c") # return {"blog": blog, "cate_list": cate_list, "date_list": date_list, "tag_list": tag_list}
re_path(r'^(?P<username>\w+)/articles/(?P<article_id>\d+)$', views.article_detail),
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>home_site</title> <link rel="stylesheet" href="/static/blog/bs/css/bootstrap.css"> <script src="/static/blog/js/jquery-3.3.1.min.js"></script> <script src="/static/blog/bs/js/bootstrap.min.js"></script> <style type="text/css"> * { margin: 0; padding: 0; } .header { width: 100%; height: 60px; background-color: #369; } .header .title { font-size: 18px; font-weight: 100; line-height: 60px; color: white; margin-left: 15px; margin-top: -10px; } .backend { float: right; color: white; text-decoration: none; font-size: 14px; margin-right: 10px; margin-top: 10px; } .pub_info { margin-top: 10px; color: darkgray; } </style> </head> <body> <div class="header"> <div class="content"> <p class="title"> <span>{{ blog.title }}</span> <a href="" class="backend">管理</a> </p> </div> </div> <div class="container"> <div class="row"> <div class="col-md-3"> <div class="panel panel-warning"> <div class="panel-heading">個人標籤</div> <div class="panel-body"> {% for tag in tag_list %} <p><a href="/{{ 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 cate in cate_list %} <p><a href="/{{ username }}/category/{{ cate.0 }}"> {{ cate.0 }}({{ tag.1 }})</a></p> {% endfor %} </div> </div> <div class="panel panel-success"> <div class="panel-heading">隨筆歸檔</div> <div class="panel-body"> {% for date in date_list %} <p><a href="/{{ username }}/archive/{{ date.0 }}"> {{ date.0 }}({{ tag.1 }})</a></p> {% endfor %} </div> </div> </div> <div class="col-md-9"> {% block content %} {% endblock %} </div> </div> </div> </body> </html>
{% extends 'base.html' %}
from django.shortcuts import render, HttpResponse, redirect # Create your views here. from django.http import JsonResponse from django.contrib import auth from blog.Myforms import UserForm from blog.models import UserInfo from blog import models from django.db.models import Count def login(request): """ 登陸; :param request: :return: """ if request.method == "POST": response = {"user": None, "msg": None} user = request.POST.get("user") pwd = request.POST.get("pwd") valid_code = request.POST.get("valid_code") valid_code_str = request.session.get("valid_code_str") if valid_code.upper() == valid_code_str.upper(): user = auth.authenticate(username=user, password=pwd) if user: auth.login(request, user) response["user"] = user.username else: response["msg"] = "用戶名或者密碼錯誤!" else: response["msg"] = "驗證碼錯誤!" return JsonResponse(response) return render(request, "login.html") def index(request): """ 首頁; :param request: :return: """ article_list = models.Article.objects.all() return render(request, "index.html", {"article_list": article_list}) def logout(request): auth.logout(request) # 等同於request.session.flush() return redirect("/login/") def get_valid_code_img(request): """ 基於PIL模塊動態生成響應狀態碼圖片; :param request: :return: """ from blog.utils.validCode import get_valid_code_img data = get_valid_code_img(request) return HttpResponse(data) def register(request): """ 註冊; :param request: :return: """ # if request.method == "POST": if request.is_ajax(): # print(request.POST) form = UserForm(request.POST) response = {"user": None, "msg": None} if form.is_valid(): response["user"] = form.cleaned_data.get("user") # 生成一條用戶記錄; user = form.cleaned_data.get("user") pwd = form.cleaned_data.get("pwd") email = form.cleaned_data.get("email") avatar_obj = request.FILES.get("avatar") ''' if avatar_obj: user_obj = UserInfo.objects.create_user(username=user,password=pwd,email=email,avatar = avatar_obj ) else: user_obj = UserInfo.objects.create_user(username=user, password=pwd, email=email) ''' extra = {} if avatar_obj: extra["avatar"] = avatar_obj UserInfo.objects.create_user(username=user, password=pwd, email=email, **extra) else: # print(form.cleaned_data) # print(form.errors) response["msg"] = form.errors return JsonResponse(response) form = UserForm() return render(request, "register.html", {"form": form}) def get_query_data(username): user = UserInfo.objects.filter(username=username).first() # 判斷用戶是否存在! if not user: return render(request, "not_found.html") # 查詢當前站點對象 blog = user.blog # 查詢當前站點的每個分類名稱以及對應的文章數 cate_list = models.Category.objects.filter(blog=blog).values("pk").annotate(c=Count("article__title")).values_list( "title", "c") tag_list = models.Tag.objects.filter(blog=blog).values("pk").annotate(c=Count("article")).values_list("title", "c") date_list = models.Article.objects.filter(user=user).extra( select={"y_m_date": "date_format(create_time,'%%Y-%%m')"}).values("y_m_date").annotate( c=Count("nid")).values_list("y_m_date", "c") return {"blog": blog, "cate_list": cate_list, "date_list": date_list, "tag_list": tag_list} def article_detail(request, username, article_id): context = get_query_data(username) return render(request, "article_detail.html", context) def home_site(request, username, **kwargs): """ 我的站點視圖函數 :param request: :return: """ print("kwargs", kwargs) # 區分訪問是的站點頁面仍是站點下的跳轉頁面; print("username", username) user = UserInfo.objects.filter(username=username).first() # 判斷用戶是否存在! if not user: return render(request, "not_found.html") # 查詢當前站點對象 blog = user.blog # 1 當前用戶或者當前站點對應全部文章 # 基於對象查詢 # article_list=user.article_set.all() # 基於 __ article_list = models.Article.objects.filter(user=user) if kwargs: condition = kwargs.get("condition") param = kwargs.get("param") # 2012-12 if condition == "category": article_list = article_list.filter(category__title=param) elif condition == "tag": article_list = article_list.filter(tags__title=param) else: year, month = param.split("-") article_list = article_list.filter(create_time__year=year, create_time__month=month) # 每個後的表模型.objects.values("pk").annotate(聚合函數(關聯表__統計字段)).values("表模型的全部字段以及統計字段") # 查詢每個分類名稱以及對應的文章數 # ret=models.Category.objects.values("pk").annotate(c=Count("article__title")).values("title","c") # print(ret) # 查詢當前站點的每個分類名稱以及對應的文章數 cate_list = models.Category.objects.filter(blog=blog).values("pk").annotate(c=Count("article__title")).values_list( "title", "c") print(cate_list) # 查詢當前站點的每個標籤名稱以及對應的文章數 tag_list = models.Tag.objects.filter(blog=blog).values("pk").annotate(c=Count("article")).values_list("title", "c") print(tag_list) # 查詢當前站點每個年月的名稱以及對應的文章數 # ret=models.Article.objects.extra(select={"is_recent":"create_time > '2018-09-05'"}).values("title","is_recent") # print(ret) # 方式1: date_list = models.Article.objects.filter(user=user).extra( select={"y_m_date": "date_format(create_time,'%%Y-%%m')"}).values("y_m_date").annotate( c=Count("nid")).values_list("y_m_date", "c") print(date_list) # 方式2: # from django.db.models.functions import TruncMonth # # ret=models.Article.objects.filter(user=user).annotate(month=TruncMonth("create_time")).values("month").annotate(c=Count("nid")).values_list("month","c") # print("ret----->",ret) return render(request, "home_site.html", {"username": username, "blog": blog, "article_list": article_list, "tag_list": tag_list, "cate_list": cate_list, "date_list": date_list})
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>home_site</title> <link rel="stylesheet" href="/static/blog/bs/css/bootstrap.css"> <script src="/static/blog/js/jquery-3.3.1.min.js"></script> <script src="/static/blog/bs/js/bootstrap.min.js"></script> <style type="text/css"> * { margin: 0; padding: 0; } .header { width: 100%; height: 60px; background-color: #369; } .header .title { font-size: 18px; font-weight: 100; line-height: 60px; color: white; margin-left: 15px; margin-top: -10px; } .backend { float: right; color: white; text-decoration: none; font-size: 14px; margin-right: 10px; margin-top: 10px; } .pub_info { margin-top: 10px; color: darkgray; } </style> </head> <body> <div class="header"> <div class="content"> <p class="title"> <span>{{ blog.title }}</span> <a href="" class="backend">管理</a> </p> </div> </div> <div class="container"> <div class="row"> <div class="col-md-3 menu"> {% load my_tags %} {% get_classification_style username %} </div> <div class="col-md-9"> {% block content %} {% endblock %} </div> </div> </div> </body> </html>
# @register.simple_tag @register.inclusion_tag("classification.html") def get_classification_style(username): user = models.UserInfo.objects.filter(username=username).first() # 查詢當前站點對象 blog = user.blog # 查詢當前站點的每個分類名稱以及對應的文章數 cate_list = models.Category.objects.filter(blog=blog).values("pk").annotate(c=Count("article__title")).values_list( "title", "c") tag_list = models.Tag.objects.filter(blog=blog).values("pk").annotate(c=Count("article")).values_list("title", "c") date_list = models.Article.objects.filter(user=user).extra( select={"y_m_date": "date_format(create_time,'%%Y-%%m')"}).values("y_m_date").annotate( c=Count("nid")).values_list("y_m_date", "c") return {"blog": blog, "cate_list": cate_list, "date_list": date_list, "tag_list": tag_list}
<div> <div class="panel panel-warning"> <div class="panel-heading">個人標籤</div> <div class="panel-body"> {% for tag in tag_list %} <p><a href="/{{ 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 cate in cate_list %} <p><a href="/{{ username }}/category/{{ cate.0 }}"> {{ cate.0 }}({{ tag.1 }})</a></p> {% endfor %} </div> </div> <div class="panel panel-success"> <div class="panel-heading">隨筆歸檔</div> <div class="panel-body"> {% for date in date_list %} <p><a href="/{{ username }}/archive/{{ date.0 }}"> {{ date.0 }}({{ tag.1 }})</a></p> {% endfor %} </div> </div> </div>
{% extends 'base.html' %} {% block content %} <h3 class="text-center">{{ article_obj.title }}</h3> <div class="cont"> {{ article_obj.content }} </div> {% endblock %}
{% extends 'base.html' %} {% block content %} <h3 class="text-center">{{ article_obj.title }}</h3> <div class="cont"> {{ article_obj.content|safe }} </div> {% endblock %}
{% extends 'base.html' %} {% block content %} <h3 class="text-center">{{ article_obj.title }}</h3> <div class="cont"> {{ article_obj.content|safe }} </div> <div id="div_digg"> <div class="diggit"> <span class="diggnum" id="digg_count">1</span> </div> <div class="buryit"> <span class="burynum" id="bury_count">0</span> </div> <div class="clear"></div> <div class="diggword" id="digg_tips" style="color:red;"></div> </div> {% endblock %}
* {
margin: 0;
padding: 0;
}
.header {
width: 100%;
height: 60px;
background-color: #369;
}
.header .title {
font-size: 18px;
font-weight: 100;
line-height: 60px;
color: white;
margin-left: 15px;
margin-top: -10px;
}
.backend {
float: right;
color: white;
text-decoration: none;
font-size: 14px;
margin-right: 10px;
margin-top: 10px;
}
.pub_info {
margin-top: 10px;
color: darkgray;
}
.article_info .title {
margin-bottom: 20px;
}
#div_digg {
float: right;
margin-bottom: 10px;
margin-right: 30px;
font-size: 12px;
width: 125px;
text-align: center;
margin-top: 10px;
}
.diggit {
float: left;
width: 46px;
height: 52px;
background: url(/static/blog/img/upup.gif) no-repeat;
text-align: center;
cursor: pointer;
margin-top: 2px;
padding-top: 5px;
}
.buryit {
float: right;
margin-left: 20px;
width: 46px;
height: 52px;
background: url(/static/blog/img/downdown.gif) no-repeat;
text-align: center;
cursor: pointer;
margin-top: 2px;
padding-top: 5px;
}
.clear{
clear: both;
}
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>home_site</title> <link rel="stylesheet" href="/static/blog/bs/css/bootstrap.css"> <script src="/static/blog/js/jquery-3.3.1.min.js"></script> <script src="/static/blog/bs/js/bootstrap.min.js"></script> <link rel="stylesheet" href="/static/blog/css/home_site.css"> <link rel="stylesheet" href="/static/blog/css/article_detail.css"> </head>
{% extends 'base.html' %} {% block content %} <h3 class="text-center">{{ article_obj.title }}</h3> <div class="cont"> {{ article_obj.content|safe }} </div> <div id="div_digg"> <div class="diggit action"> <span class="diggnum" id="digg_count">1</span> </div> <div class="buryit action"> <span class="burynum" id="bury_count">0</span> </div> <div class="clear"></div> <div class="diggword" id="digg_tips" style="color:red;"></div> </div> <script> $("#div_digg .action").click(function () { var is_up = $(this).hasClass("diggit") alert(is_up) }) </script> {% endblock %}
{% extends 'base.html' %} {% block content %} {% csrf_token %} <h3 class="text-center">{{ article_obj.title }}</h3> <div class="cont"> {{ article_obj.content|safe }} </div> <div id="div_digg"> <div class="diggit action"> <span class="diggnum" id="digg_count">{{ article_obj.up_count }}</span> </div> <div class="buryit action"> <span class="burynum" id="bury_count">{{ article_obj.down_count }}</span> </div> <div class="clear"></div> <div class="diggword" id="digg_tips" style="color:red;"></div> </div> <script> $("#div_digg .action").click(function () { var is_up = $(this).hasClass("diggit"); alert(is_up) //傳Ajax事件; $.ajax({ url: "/digg/", type: "post", data: { "csrfmiddlewaretoken": $("[name = 'csrfmiddlewaretoken']").val(), "is_up": is_up, "article_id": "{{ article_obj.pk }}", }, success: function (data) { console.log(data) } }) }); </script> {% endblock %}
def digg(request): """ 點贊視圖函數; :param request: :return: """ print(request.POST) article_id = request.POST.get("article_id") is_up = json.loads(request.POST.get("is_up")) # 點贊人即當前登陸人; user_id = request.user.pk ard = models.ArticleUpDown.objects.create(user_id=user_id, article_id=article_id, is_up=is_up) return HttpResponse("ok")
"""cnblogs URL Configuration The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/2.1/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: path('', views.home, name='home') Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') Including another URLconf 1. Import the include() function: from django.urls import include, path 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ from django.contrib import admin from django.urls import path, re_path from blog import views from django.views.static import serve from cnblogs import settings urlpatterns = [ path('admin/', admin.site.urls), path('login/', views.login), path('index/', views.index), path('logout/', views.logout), re_path('^$', views.index), path('get_validCode_img/', views.get_valid_code_img), path('register/', views.register), path('digg/', views.digg), # media配置; re_path(r'media/(?P<path>.*)$', serve, {"document_root": settings.MEDIA_ROOT}), re_path(r'^(?P<username>\w+)/articles/(?P<article_id>\d+)$', views.article_detail), # 我的站點下的跳轉URL;# 接受的參數,home_site(request,username,condition,param) re_path(r'^(?P<username>\w+)/(?P<condition>tag|category|archive)/(?P<param>.*)/$', views.home_site), # re_path(r'^(?P<username>\w+)/category/.*/$', views.home_site), # re_path(r'^(?P<username>\w+)/archive/.*/$', views.home_site), # 我的站點URL;#接收的參數home_site(request,username="cxz") re_path(r'^(?P<username>\w+)/$', views.home_site), ]
def digg(request): """ 點贊視圖函數; :param request: :return: """ print(request.POST) article_id = request.POST.get("article_id") is_up = json.loads(request.POST.get("is_up")) # 點贊人即當前登陸人; user_id = request.user.pk ard = models.ArticleUpDown.objects.create(user_id=user_id, article_id=article_id, is_up=is_up) if is_up: models.Article.objects.filter(pk=article_id).update(up_count=F("up_count") + 1) return HttpResponse("ok")
def digg(request): """ 點贊視圖函數; :param request: :return: """ print(request.POST) article_id = request.POST.get("article_id") is_up = json.loads(request.POST.get("is_up")) # 點贊、點踩的人即當前登陸人; user_id = request.user.pk obj = models.ArticleUpDown.objects.filter(user_id=user_id, article_id=article_id).first() response = {"state": True} if not obj: ard = models.ArticleUpDown.objects.create(user_id=user_id, article_id=article_id, is_up=is_up) queryset = models.Article.objects.filter(pk=article_id) if is_up: queryset.update(up_count=F("up_count") + 1) else: queryset.update(down_count=F("down_count") + 1) else: response["state"] = False response["handled"] = obj.is_up return JsonResponse(response)
<script> $("#div_digg .action").click(function () { var is_up = $(this).hasClass("diggit"); // alert(is_up) //傳Ajax事件; $.ajax({ url: "/digg/", type: "post", data: { "csrfmiddlewaretoken": $("[name = 'csrfmiddlewaretoken']").val(), "is_up": is_up, "article_id": "{{ article_obj.pk }}", }, success: function (data) { console.log(data); if (data.state){ }else { if (data.handled){ $("#digg_tips").html("您已經推薦過!") }else{ $("#digg_tips").html("您已經反對過!") } setTimeout(function () { $("#digg_tips").html("") },1000) } } }) }); </script>
<script> $("#div_digg .action").click(function () { var is_up = $(this).hasClass("diggit"); // alert(is_up) //傳Ajax事件; $.ajax({ url: "/digg/", type: "post", data: { "csrfmiddlewaretoken": $("[name = 'csrfmiddlewaretoken']").val(), "is_up": is_up, "article_id": "{{ article_obj.pk }}", }, success: function (data) { console.log(data); if (data.state) { if (is_up) { var val = parseInt($("#digg_count").text()); $("#digg_count").text(val + 1); } else { var val = parseInt($("#bury_count").text()); $("#bury_count").text(val + 1); } } else { if (data.handled) { $("#digg_tips").html("您已經推薦過!") } else { $("#digg_tips").html("您已經反對過!") } setTimeout(function () { $("#digg_tips").html("") }, 1000) } } }) }); </script>
{% extends 'base.html' %} {% block content %} {% csrf_token %} <h3 class="text-center">{{ article_obj.title }}</h3> <div class="cont"> {{ article_obj.content|safe }} </div> <div id="div_digg"> <div class="diggit action"> <span class="diggnum" id="digg_count">{{ article_obj.up_count }}</span> </div> <div class="buryit action"> <span class="burynum" id="bury_count">{{ article_obj.down_count }}</span> </div> <div class="clear"></div> <div class="diggword" id="digg_tips" style="color:red;"></div> </div> <script> $("#div_digg .action").click(function () { var is_up = $(this).hasClass("diggit"); // alert(is_up) //傳Ajax事件; $obj = $(this).children("span"); $.ajax({ url: "/digg/", type: "post", data: { "csrfmiddlewaretoken": $("[name = 'csrfmiddlewaretoken']").val(), "is_up": is_up, "article_id": "{{ article_obj.pk }}", }, success: function (data) { console.log(data); if (data.state) { var val = parseInt($("#digg_count").text()); $obj.text(val + 1); } else { var val = data.handled ? "您已經推薦過!" : "您已經反對過!"; $("#digg_tips").html(val); setTimeout(function () { $("#digg_tips").html("") }, 1000) } } }) }); </script> {% endblock %}
{% extends 'base.html' %} {% block content %} {% csrf_token %} <h3 class="text-center">{{ article_obj.title }}</h3> <div class="cont"> {{ article_obj.content|safe }} </div> <div class="clearfix"> <div id="div_digg"> <div class="diggit action"> <span class="diggnum" id="digg_count">{{ article_obj.up_count }}</span> </div> <div class="buryit action"> <span class="burynum" id="bury_count">{{ article_obj.down_count }}</span> </div> <div class="clear"></div> <div class="diggword" id="digg_tips" style="color:red;"></div> </div> </div> <div class="commonts"> <p>發表評論</p> <p> 暱稱:<input type="text" id="tbCommentAuthor" class="author" disabled="disabled" size="50" value="{{ request.user.username }}"> </p> <p>評論內容:</p> <textarea name="" id="" cols="60" rows="10"></textarea> <p> <button class="btn btn-default common_btn">提交評論</button> </p> </div> <script> $("#div_digg .action").click(function () { var is_up = $(this).hasClass("diggit"); // alert(is_up) //傳Ajax事件; $obj = $(this).children("span"); $.ajax({ url: "/digg/", type: "post", data: { "csrfmiddlewaretoken": $("[name = 'csrfmiddlewaretoken']").val(), "is_up": is_up, "article_id": "{{ article_obj.pk }}", }, success: function (data) { console.log(data); if (data.state) { var val = parseInt($("#digg_count").text()); $obj.text(val + 1); } else { var val = data.handled ? "您已經推薦過!" : "您已經反對過!"; $("#digg_tips").html(val); setTimeout(function () { $("#digg_tips").html("") }, 1000) } } }) }); </script> {% endblock %}
{% extends 'base.html' %} {% block content %} {% csrf_token %} <h3 class="text-center">{{ article_obj.title }}</h3> <div class="cont"> {{ article_obj.content|safe }} </div> <div class="clearfix"> <div id="div_digg"> <div class="diggit action"> <span class="diggnum" id="digg_count">{{ article_obj.up_count }}</span> </div> <div class="buryit action"> <span class="burynum" id="bury_count">{{ article_obj.down_count }}</span> </div> <div class="clear"></div> <div class="diggword" id="digg_tips" style="color:red;"></div> </div> </div> <div class="commonts"> <p>發表評論</p> <p> 暱稱:<input type="text" id="tbCommentAuthor" class="author" disabled="disabled" size="50" value="{{ request.user.username }}"> </p> <p>評論內容:</p> <textarea name="" id="comment_content" cols="60" rows="10"></textarea> <p> <button class="btn btn-default common_btn">提交評論</button> </p> </div> <script> //點贊請求; $("#div_digg .action").click(function () { var is_up = $(this).hasClass("diggit"); // alert(is_up) //傳Ajax事件; $obj = $(this).children("span"); $.ajax({ url: "/digg/", type: "post", data: { "csrfmiddlewaretoken": $("[name = 'csrfmiddlewaretoken']").val(), "is_up": is_up, "article_id": "{{ article_obj.pk }}", }, success: function (data) { console.log(data); if (data.state) { var val = parseInt($("#digg_count").text()); $obj.text(val + 1); } else { var val = data.handled ? "您已經推薦過!" : "您已經反對過!"; $("#digg_tips").html(val); setTimeout(function () { $("#digg_tips").html("") }, 1000) } } }) }); //評論請求; $(".common_btn").click(function () { var pid = ""; var content = $("#comment_content").val(); $.ajax({ url: "/comment/", type: "post", data: { "csrfmiddlewaretoken": $("[name = 'csrfmiddlewaretoken']").val(), "article_id": "{{ article_obj.pk }}", "content": content, pid:pid, }, success: function (data) { console.log(data); //清空評論框; $("#comment_content").val("") } }) }) </script> {% endblock %}
def comment(request): print(request.POST) article_id = request.POST.get("article_id") pid = request.POST.get("pid") content = request.POST.get("content") user_id = request.user.pk comment_obj = models.Comment.objects.create(user_id=user_id, article_id=article_id, content=content, parent_comment_id=pid) return HttpResponse("comment")
{% extends 'base.html' %} {% block content %} {% csrf_token %} <h3 class="text-center">{{ article_obj.title }}</h3> <div class="cont"> {{ article_obj.content|safe }} </div> <div class="clearfix"> <div id="div_digg"> <div class="diggit action"> <span class="diggnum" id="digg_count">{{ article_obj.up_count }}</span> </div> <div class="buryit action"> <span class="burynum" id="bury_count">{{ article_obj.down_count }}</span> </div> <div class="clear"></div> <div class="diggword" id="digg_tips" style="color:red;"></div> </div> </div> <div class="commonts"> <p>評論列表</p> <ul class="list-group comment_list"> {% for comment in comment_list %} <li class="list-group-item"> <div> <a href="">#{{ forloop.counter }}樓</a> <span>{{ comment.create_time|date:"Y-m-d H:i" }}</span> <a href=""><span>{{ comment.user.username }}</span></a> <a href="" class="pull-right">回覆</a> </div> <div class="comment_con"> <p>{{ comment.content }}</p> </div> </li> {% endfor %} </ul> <p>發表評論</p> <p> 暱稱:<input type="text" id="tbCommentAuthor" class="author" disabled="disabled" size="50" value="{{ request.user.username }}"> </p> <p>評論內容:</p> <textarea name="" id="comment_content" cols="60" rows="10"></textarea> <p> <button class="btn btn-default common_btn">提交評論</button> </p> </div> <script> //點贊請求; $("#div_digg .action").click(function () { var is_up = $(this).hasClass("diggit"); // alert(is_up) //傳Ajax事件; $obj = $(this).children("span"); $.ajax({ url: "/digg/", type: "post", data: { "csrfmiddlewaretoken": $("[name = 'csrfmiddlewaretoken']").val(), "is_up": is_up, "article_id": "{{ article_obj.pk }}", }, success: function (data) { console.log(data); if (data.state) { var val = parseInt($("#digg_count").text()); $obj.text(val + 1); } else { var val = data.handled ? "您已經推薦過!" : "您已經反對過!"; $("#digg_tips").html(val); setTimeout(function () { $("#digg_tips").html("") }, 1000) } } }) }); //評論請求; $(".common_btn").click(function () { var pid = ""; var content = $("#comment_content").val(); $.ajax({ url: "/comment/", type: "post", data: { "csrfmiddlewaretoken": $("[name = 'csrfmiddlewaretoken']").val(), "article_id": "{{ article_obj.pk }}", "content": content, pid: pid, }, success: function (data) { console.log(data); //清空評論框; $("#comment_content").val("") } }) }) </script> {% endblock %}
.article_info .title {
margin-bottom: 20px;
}
#div_digg {
float: right;
margin-bottom: 10px;
margin-right: 30px;
font-size: 12px;
width: 125px;
text-align: center;
margin-top: 10px;
}
.diggit {
float: left;
width: 46px;
height: 52px;
background: url(/static/blog/img/upup.gif) no-repeat;
text-align: center;
cursor: pointer;
margin-top: 2px;
padding-top: 5px;
}
.buryit {
float: right;
margin-left: 20px;
width: 46px;
height: 52px;
background: url(/static/blog/img/downdown.gif) no-repeat;
text-align: center;
cursor: pointer;
margin-top: 2px;
padding-top: 5px;
}
.clear {
clear: both;
}
input.author {
background-image: url(/static/blog/img/icon_form.gif);
background-repeat: no-repeat;
border: 1px solid #ccc;
padding: 4px 4px 4px 30px;
width: 300px;
font-size: 13px;
background-position: 3px -3px;
}
.comment_con{
margin-top: 10px;
}
{% extends 'base.html' %} {% block content %} {% csrf_token %} <h3 class="text-center">{{ article_obj.title }}</h3> <div class="cont"> {{ article_obj.content|safe }} </div> <div class="clearfix"> <div id="div_digg"> <div class="diggit action"> <span class="diggnum" id="digg_count">{{ article_obj.up_count }}</span> </div> <div class="buryit action"> <span class="burynum" id="bury_count">{{ article_obj.down_count }}</span> </div> <div class="clear"></div> <div class="diggword" id="digg_tips" style="color:red;"></div> </div> </div> <div class="commonts"> <p>評論列表</p> <ul class="list-group comment_list"> {% for comment in comment_list %} <li class="list-group-item"> <div> <a href="">#{{ forloop.counter }}樓</a> <span>{{ comment.create_time|date:"Y-m-d H:i" }}</span> <a href=""><span>{{ comment.user.username }}</span></a> <a href="" class="pull-right">回覆</a> </div> <div class="comment_con"> <p>{{ comment.content }}</p> </div> </li> {% endfor %} </ul> <p>發表評論</p> <p> 暱稱:<input type="text" id="tbCommentAuthor" class="author" disabled="disabled" size="50" value="{{ request.user.username }}"> </p> <p>評論內容:</p> <textarea name="" id="comment_content" cols="60" rows="10"></textarea> <p> <button class="btn btn-default common_btn">提交評論</button> </p> </div> <script> //點贊請求; $("#div_digg .action").click(function () { var is_up = $(this).hasClass("diggit"); // alert(is_up) //傳Ajax事件; $obj = $(this).children("span"); $.ajax({ url: "/digg/", type: "post", data: { "csrfmiddlewaretoken": $("[name = 'csrfmiddlewaretoken']").val(), "is_up": is_up, "article_id": "{{ article_obj.pk }}", }, success: function (data) { console.log(data); if (data.state) { var val = parseInt($("#digg_count").text()); $obj.text(val + 1); } else { var val = data.handled ? "您已經推薦過!" : "您已經反對過!"; $("#digg_tips").html(val); setTimeout(function () { $("#digg_tips").html("") }, 1000) } } }) }); //評論請求; $(".common_btn").click(function () { var pid = ""; var content = $("#comment_content").val(); $.ajax({ url: "/comment/", type: "post", data: { "csrfmiddlewaretoken": $("[name = 'csrfmiddlewaretoken']").val(), "article_id": "{{ article_obj.pk }}", "content": content, pid: pid, }, success: function (data) { console.log(data); var create_time = data.create_time; var username = data.username; var content = data.content; var s = ` <li class="list-group-item"> <div> <span>${create_time}</span> <a href=""><span>${username}</span></a> </div> <div class="comment_con"> <p>${content}</p> </div> </li>`; $("ul.comment_list").append(s); //清空評論框; $("#comment_content").val("") } }) }) </script> {% endblock %}
def comment(request): print(request.POST) article_id = request.POST.get("article_id") pid = request.POST.get("pid") content = request.POST.get("content") user_id = request.user.pk comment_obj = models.Comment.objects.create(user_id=user_id, article_id=article_id, content=content, parent_comment_id=pid) response = {} response["create_time"] = comment_obj.create_time.strftime("%Y-%m-%d %X") response["username"] = request.user.username response["content"] = content return JsonResponse(response)
{% extends 'base.html' %} {% block content %} {% csrf_token %} <h3 class="text-center">{{ article_obj.title }}</h3> <div class="cont"> {{ article_obj.content|safe }} </div> <div class="clearfix"> <div id="div_digg"> <div class="diggit action"> <span class="diggnum" id="digg_count">{{ article_obj.up_count }}</span> </div> <div class="buryit action"> <span class="burynum" id="bury_count">{{ article_obj.down_count }}</span> </div> <div class="clear"></div> <div class="diggword" id="digg_tips" style="color:red;"></div> </div> </div> <div class="commonts"> <p>評論列表</p> <ul class="list-group comment_list"> {% for comment in comment_list %} <li class="list-group-item"> <div> <a href="">#{{ forloop.counter }}樓</a> <span>{{ comment.create_time|date:"Y-m-d H:i" }}</span> <a href=""><span>{{ comment.user.username }}</span></a> <a class="pull-right reply_btn" username = "{{ comment.user.username }}" >回覆</a> </div> <div class="comment_con"> <p>{{ comment.content }}</p> </div> </li> {% endfor %} </ul> <p>發表評論</p> <p> 暱稱:<input type="text" id="tbCommentAuthor" class="author" disabled="disabled" size="50" value="{{ request.user.username }}"> </p> <p>評論內容:</p> <textarea name="" id="comment_content" cols="60" rows="10"></textarea> <p> <button class="btn btn-default common_btn">提交評論</button> </p> </div> <script> //點贊請求; $("#div_digg .action").click(function () { var is_up = $(this).hasClass("diggit"); // alert(is_up) //傳Ajax事件; $obj = $(this).children("span"); $.ajax({ url: "/digg/", type: "post", data: { "csrfmiddlewaretoken": $("[name = 'csrfmiddlewaretoken']").val(), "is_up": is_up, "article_id": "{{ article_obj.pk }}", }, success: function (data) { console.log(data); if (data.state) { var val = parseInt($("#digg_count").text()); $obj.text(val + 1); } else { var val = data.handled ? "您已經推薦過!" : "您已經反對過!"; $("#digg_tips").html(val); setTimeout(function () { $("#digg_tips").html("") }, 1000) } } }) }); //評論請求; $(".common_btn").click(function () { var pid = ""; var content = $("#comment_content").val(); $.ajax({ url: "/comment/", type: "post", data: { "csrfmiddlewaretoken": $("[name = 'csrfmiddlewaretoken']").val(), "article_id": "{{ article_obj.pk }}", "content": content, pid: pid, }, success: function (data) { console.log(data); var create_time = data.create_time; var username = data.username; var content = data.content; var s = ` <li class="list-group-item"> <div> <span>${create_time}</span> <a href=""><span>${username}</span></a> </div> <div class="comment_con"> <p>${content}</p> </div> </li>`; $("ul.comment_list").append(s); //清空評論框; $("#comment_content").val("") } }) }); //回覆按鈕事件; $(".reply_btn").click(function () { $("#comment_content").focus(); var val = "@"+$(this).attr("username")+"\n"; $("#comment_content").val(val) }) </script> {% endblock %}
{% extends 'base.html' %} {% block content %} {% csrf_token %} <h3 class="text-center">{{ article_obj.title }}</h3> <div class="cont"> {{ article_obj.content|safe }} </div> <div class="clearfix"> <div id="div_digg"> <div class="diggit action"> <span class="diggnum" id="digg_count">{{ article_obj.up_count }}</span> </div> <div class="buryit action"> <span class="burynum" id="bury_count">{{ article_obj.down_count }}</span> </div> <div class="clear"></div> <div class="diggword" id="digg_tips" style="color:red;"></div> </div> </div> <div class="commonts"> <p>評論列表</p> <ul class="list-group comment_list"> {% for comment in comment_list %} <li class="list-group-item"> <div> <a href="">#{{ forloop.counter }}樓</a> <span>{{ comment.create_time|date:"Y-m-d H:i" }}</span> <a href=""><span>{{ comment.user.username }}</span></a> <a class="pull-right reply_btn" username="{{ comment.user.username }} " comment_pk="{{ comment.pk }}">回覆</a> </div> <div class="comment_con"> <p>{{ comment.content }}</p> </div> </li> {% endfor %} </ul> <p>發表評論</p> <p> 暱稱:<input type="text" id="tbCommentAuthor" class="author" disabled="disabled" size="50" value="{{ request.user.username }}"> </p> <p>評論內容:</p> <textarea name="" id="comment_content" cols="60" rows="10"></textarea> <p> <button class="btn btn-default common_btn">提交評論</button> </p> </div> <script> //點贊請求; $("#div_digg .action").click(function () { var is_up = $(this).hasClass("diggit"); // alert(is_up) //傳Ajax事件; $obj = $(this).children("span"); $.ajax({ url: "/digg/", type: "post", data: { "csrfmiddlewaretoken": $("[name = 'csrfmiddlewaretoken']").val(), "is_up": is_up, "article_id": "{{ article_obj.pk }}", }, success: function (data) { console.log(data); if (data.state) { var val = parseInt($("#digg_count").text()); $obj.text(val + 1); } else { var val = data.handled ? "您已經推薦過!" : "您已經反對過!"; $("#digg_tips").html(val); setTimeout(function () { $("#digg_tips").html("") }, 1000) } } }) }); //評論請求; var pid = ""; $(".common_btn").click(function () { var content = $("#comment_content").val(); if (pid) { var index = content.indexOf("\n"); content = content.slice(index + 1) } $.ajax({ url: "/comment/", type: "post", data: { "csrfmiddlewaretoken": $("[name = 'csrfmiddlewaretoken']").val(), "article_id": "{{ article_obj.pk }}", "content": content, pid: pid, }, success: function (data) { console.log(data); var create_time = data.create_time; var username = data.username; var content = data.content; var s = ` <li class="list-group-item"> <div> <span>${create_time}</span> <a href=""><span>${username}</span></a> </div> <div class="comment_con"> <p>${content}</p> </div> </li>`; $("ul.comment_list").append(s); //清空評論框; pid = ""; $("#comment_content").val("") } }) }); //回覆按鈕事件; $(".reply_btn").click(function () { $("#comment_content").focus(); var val = "@" + $(this).attr("username") + "\n"; $("#comment_content").val(val); pid = $(this).attr("comment_pk"); }) </script> {% endblock %}
{% if comment.parent_comment_id %} <div class="pid_info well"> <p> {{ comment.parent_comment.user.username }}:{{ comment.parent_comment.content }} </p> </div> {% endif %}
var pid = ""; $(".common_btn").click(function () { var content = $("#comment_content").val(); if (pid) { var index = content.indexOf("\n"); content = content.slice(index + 1) } $.ajax({ url: "/comment/", type: "post", data: { "csrfmiddlewaretoken": $("[name = 'csrfmiddlewaretoken']").val(), "article_id": "{{ article_obj.pk }}", "content": content, pid: pid, }, success: function (data) { console.log(data); var create_time = data.create_time; var username = data.username; var content = data.content; var s = ` <li class="list-group-item"> <div> <span>${create_time}</span> <a href=""><span>${username}</span></a> </div> <div class="comment_con"> <p>${content}</p> </div> </li>`; $("ul.comment_list").append(s); //清空評論框; pid = ""; $("#comment_content").val("") } }) });
path('get_comment_tree/', views.get_comment_tree),
def get_comment_tree(request): article_id = request.GET.get("article_id") ret = list(models.Comment.objects.filter(article_id=article_id).values("pk", "content", "parent_comment_id")) return JsonResponse(ret, safe=False)
{% extends 'base.html' %} {% block content %} {% csrf_token %} <h3 class="text-center">{{ article_obj.title }}</h3> <div class="cont"> {{ article_obj.content|safe }} </div> <div class="clearfix"> <div id="div_digg"> <div class="diggit action"> <span class="diggnum" id="digg_count">{{ article_obj.up_count }}</span> </div> <div class="buryit action"> <span class="burynum" id="bury_count">{{ article_obj.down_count }}</span> </div> <div class="clear"></div> <div class="diggword" id="digg_tips" style="color:red;"></div> </div> </div> <div class="commonts list-group"> <p class="tree_btn">評論樹</p> <div class="comment_tree"> </div> <script> $(".tree_btn").click(function () { $.ajax({ url: "/get_comment_tree", type: "get", data: { article_id: "{{ article_obj.pk }}" }, success: function (data) { console.log(data) $.each(data, function (index, comment_object) { var pk = comment_object.pk; var content = comment_object.content; var parent_comment_id = comment_object.parent_comment_id; if (!parent_comment_id) { var s = '<div comment_id=' + pk + '><span>' + content + '</span> </div>'; $(".comment_tree").append(s) } }) } }) }) </script> <p>評論列表</p> <ul class="list-group comment_list"> {% for comment in comment_list %} <li class="list-group-item"> <div> <a href="">#{{ forloop.counter }}樓</a> <span>{{ comment.create_time|date:"Y-m-d H:i" }}</span> <a href=""><span>{{ comment.user.username }}</span></a> <a class="pull-right reply_btn" username="{{ comment.user.username }} " comment_pk="{{ comment.pk }}">回覆</a> </div> {% if comment.parent_comment_id %} <div class="pid_info well"> <p> {{ comment.parent_comment.user.username }}:{{ comment.parent_comment.content }} </p> </div> {% endif %} <div class="comment_con"> <p>{{ comment.content }}</p> </div> </li> {% endfor %} </ul> <p>發表評論</p> <p> 暱稱:<input type="text" id="tbCommentAuthor" class="author" disabled="disabled" size="50" value="{{ request.user.username }}"> </p> <p>評論內容:</p> <textarea name="" id="comment_content" cols="60" rows="10"></textarea> <p> <button class="btn btn-default common_btn">提交評論</button> </p> </div> <script> //點贊請求; $("#div_digg .action").click(function () { var is_up = $(this).hasClass("diggit"); // alert(is_up) //傳Ajax事件; $obj = $(this).children("span"); $.ajax({ url: "/digg/", type: "post", data: { "csrfmiddlewaretoken": $("[name = 'csrfmiddlewaretoken']").val(), "is_up": is_up, "article_id": "{{ article_obj.pk }}", }, success: function (data) { console.log(data); if (data.state) { var val = parseInt($("#digg_count").text()); $obj.text(val + 1); } else { var val = data.handled ? "您已經推薦過!" : "您已經反對過!"; $("#digg_tips").html(val); setTimeout(function () { $("#digg_tips").html("") }, 1000) } } }) }); //評論請求; var pid = ""; $(".common_btn").click(function () { var content = $("#comment_content").val(); if (pid) { var index = content.indexOf("\n"); content = content.slice(index + 1) } $.ajax({ url: "/comment/", type: "post", data: { "csrfmiddlewaretoken": $("[name = 'csrfmiddlewaretoken']").val(), "article_id": "{{ article_obj.pk }}", "content": content, pid: pid, }, success: function (data) { console.log(data); var create_time = data.create_time; var username = data.username; var content = data.content; var s = ` <li class="list-group-item"> <div> <span>${create_time}</span> <a href=""><span>${username}</span></a> </div> <div class="comment_con"> <p>${content}</p> </div> </li>`; $("ul.comment_list").append(s); //清空評論框; pid = ""; $("#comment_content").val("") } }) }); //回覆按鈕事件; $(".reply_btn").click(function () { $("#comment_content").focus(); var val = "@" + $(this).attr("username") + "\n"; $("#comment_content").val(val); pid = $(this).attr("comment_pk"); }) </script> {% endblock %}
{% extends 'base.html' %} {% block content %} {% csrf_token %} <h3 class="text-center">{{ article_obj.title }}</h3> <div class="cont"> {{ article_obj.content|safe }} </div> <div class="clearfix"> <div id="div_digg"> <div class="diggit action"> <span class="diggnum" id="digg_count">{{ article_obj.up_count }}</span> </div> <div class="buryit action"> <span class="burynum" id="bury_count">{{ article_obj.down_count }}</span> </div> <div class="clear"></div> <div class="diggword" id="digg_tips" style="color:red;"></div> </div> </div> <div class="commonts list-group"> <p class="tree_btn">評論樹</p> <div class="comment_tree"> </div> <script> $(".tree_btn").click(function () { $.ajax({ url: "/get_comment_tree", type: "get", data: { article_id: "{{ article_obj.pk }}" }, success: function (data) { console.log(data) $.each(data, function (index, comment_object) { var pk = comment_object.pk; var content = comment_object.content; var parent_comment_id = comment_object.parent_comment_id; var s = '<div class = "comment_item" comment_id=' + pk + '><span>' + content + '</span> </div>'; if (!parent_comment_id) { $(".comment_tree").append(s) } else { $("[comment_id=" + parent_comment_id + "]").append(s); } }) } }) }) </script> <p>評論列表</p> <ul class="list-group comment_list"> {% for comment in comment_list %} <li class="list-group-item"> <div> <a href="">#{{ forloop.counter }}樓</a> <span>{{ comment.create_time|date:"Y-m-d H:i" }}</span> <a href=""><span>{{ comment.user.username }}</span></a> <a class="pull-right reply_btn" username="{{ comment.user.username }} " comment_pk="{{ comment.pk }}">回覆</a> </div> {% if comment.parent_comment_id %} <div class="pid_info well"> <p> {{ comment.parent_comment.user.username }}:{{ comment.parent_comment.content }} </p> </div> {% endif %} <div class="comment_con"> <p>{{ comment.content }}</p> </div> </li> {% endfor %} </ul> <p>發表評論</p> <p> 暱稱:<input type="text" id="tbCommentAuthor" class="author" disabled="disabled" size="50" value="{{ request.user.username }}"> </p> <p>評論內容:</p> <textarea name="" id="comment_content" cols="60" rows="10"></textarea> <p> <button class="btn btn-default common_btn">提交評論</button> </p> </div> <script> //點贊請求; $("#div_digg .action").click(function () { var is_up = $(this).hasClass("diggit"); // alert(is_up) //傳Ajax事件; $obj = $(this).children("span"); $.ajax({ url: "/digg/", type: "post", data: { "csrfmiddlewaretoken": $("[name = 'csrfmiddlewaretoken']").val(), "is_up": is_up, "article_id": "{{ article_obj.pk }}", }, success: function (data) { console.log(data); if (data.state) { var val = parseInt($("#digg_count").text()); $obj.text(val + 1); } else { var val = data.handled ? "您已經推薦過!" : "您已經反對過!"; $("#digg_tips").html(val); setTimeout(function () { $("#digg_tips").html("") }, 1000) } } }) }); //評論請求; var pid = ""; $(".common_btn").click(function () { var content = $("#comment_content").val(); if (pid) { var index = content.indexOf("\n"); content = content.slice(index + 1) } $.ajax({ url: "/comment/", type: "post", data: { "csrfmiddlewaretoken": $("[name = 'csrfmiddlewaretoken']").val(), "article_id": "{{ article_obj.pk }}", "content": content, pid: pid, }, success: function (data) { console.log(data); var create_time = data.create_time; var username = data.username; var content = data.content; var s = ` <li class="list-group-item"> <div> <span>${create_time}</span> <a href=""><span>${username}</span></a> </div> <div class="comment_con"> <p>${content}</p> </div> </li>`; $("ul.comment_list").append(s); //清空評論框; pid = ""; $("#comment_content").val("") } }) }); //回覆按鈕事件; $(".reply_btn").click(function () { $("#comment_content").focus(); var val = "@" + $(this).attr("username") + "\n"; $("#comment_content").val(val); pid = $(this).attr("comment_pk"); }) </script> {% endblock %}
def get_comment_tree(request): article_id = request.GET.get("article_id") ret = list(models.Comment.objects.filter(article_id=article_id).order_by("pk").values("pk", "content", "parent_comment_id")) return JsonResponse(ret, safe=False)
<script> $.ajax({ url: "/get_comment_tree", type: "get", data: { article_id: "{{ article_obj.pk }}" }, success: function (comment_list) { console.log(comment_list); $.each(comment_list, function (index, comment_object) { var pk = comment_object.pk; var content = comment_object.content; var parent_comment_id = comment_object.parent_comment_id; var s = '<div class = "comment_item" comment_id=' + pk + '><span>' + content + '</span> </div>'; if (!parent_comment_id) { $(".comment_tree").append(s) } else { $("[comment_id=" + parent_comment_id + "]").append(s); } }) } }); </script>
def comment(request): print(request.POST) article_id = request.POST.get("article_id") pid = request.POST.get("pid") content = request.POST.get("content") user_id = request.user.pk #綁定事物操做; with transaction.atomic(): comment_obj = models.Comment.objects.create(user_id=user_id, article_id=article_id, content=content, parent_comment_id=pid) models.Article.objects.filter(pk=article_id).update(comment_count=F("comment_count") + 1) response = {} response["create_time"] = comment_obj.create_time.strftime("%Y-%m-%d %X") response["username"] = request.user.username response["content"] = content return JsonResponse(response)
EMAIL_HOST = 'smtp.exmail.qq.com' # 若是是 163 改爲 smtp.163.com EMAIL_PORT = 465 EMAIL_HOST_USER = '290799238@qq.com' # 賬號 EMAIL_HOST_PASSWORD = 'hmefdscufpbnxafbjib' # 密碼 DEFAULT_FROM_EMAIL = EMAIL_HOST_USER EMAIL_USE_SSL = True
def comment(request): print(request.POST) article_id = request.POST.get("article_id") pid = request.POST.get("pid") content = request.POST.get("content") user_id = request.user.pk article_obj = models.Article.objects.filter(pk=article_id).first() # 綁定事物操做; with transaction.atomic(): comment_obj = models.Comment.objects.create(user_id=user_id, article_id=article_id, content=content, parent_comment_id=pid) models.Article.objects.filter(pk=article_id).update(comment_count=F("comment_count") + 1) response = {} response["create_time"] = comment_obj.create_time.strftime("%Y-%m-%d %X") response["username"] = request.user.username response["content"] = content # 發送郵件; from django.core.mail import send_mail from cnblogs import settings send_mail( "您的文章%s新增了一條內容" % article_obj.title, content, settings.EMAIL_HOST_USER, ["tqtl@tqtl.org"] ) # import threading # t = threading.Thread(target=send_mail,args = ( # "您的文章%s新增了一條內容" % article_obj.title, # content, # settings.EMAIL_HOST_USER, # ["tqtl@tqtl.org"] # # )) # t.start() return JsonResponse(response)