zoukankan      html  css  js  c++  java
  • 博客项目代码整理

    目录结构如下:

    cnblog

     1 # 修改部分
     2 STATIC_URL = '/static/'
     3 STATICFILES_DIRS = [
     4     os.path.join(BASE_DIR, 'app01', "static")
     5 ]
     6 
     7 AUTH_USER_MODEL = 'app01.UserInfo'
     8 
     9 MEDIA_URL = "/media/"
    10 MEDIA_ROOT = os.path.join(BASE_DIR, "app01", "media")
    settings
     1 urlpatterns = [
     2     url(r'^admin/', admin.site.urls),
     3 
     4     url(r'^$', views.index),
     5     url(r'^login/', views.log_in),
     6     url(r'^logout/', views.logout),
     7     url(r'^get_valid_img/', views.get_valid_img),
     8     url(r'^index/', views.index),
     9 
    10     url(r'^register/', views.register),
    11     url(r'^change_pwd/', views.change_pwd),  # 修改密码 未写
    12     # blog url的分发
    13     url(r'^blog/', include("app01.url")),
    14     # media 配置
    15     url(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}),
    16 
    17     # 配置添加文章中的文件上传路径 文本编辑器的指定路径
    18     url(r'^upload_file/',views.upload_file),
    19 ]
    urls
    import os
    from django.core.wsgi import get_wsgi_application
    
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cnbolg.settings")
    
    application = get_wsgi_application()
    wsgi

    app01

     1 from django import template
     2 from app01.models import *
     3 from django.db.models import Count
     4 # from django.utils.safestring import mark_safe
     5 
     6 register = template.Library()  # register的名字是固定的,不能改变
     7 
     8 
     9 @register.inclusion_tag("blog/archive.html")
    10 def get_archive_style(username):
    11     user = UserInfo.objects.filter(username=username).first()
    12     # 当前站点
    13     blog = user.blog
    14     # 查询当前站点的所有分类
    15     # category_list=Category.objects.filter(blog_id=blog.pk)
    16     # 查询每一个分类名称以及对应的文章数
    17     cate_list = Category.objects.filter(blog=blog).annotate(c=Count("article")).values_list("title", "c")
    18 
    19     # 查询但当前站点每一个标签名称以及对应的文章数
    20     tag_list = Tag.objects.filter(blog=blog).annotate(c=Count("article")).values_list("title", "c")
    21 
    22     # 日期归档   [["2018-02",5],["2010-9",6]]
    23     date_list = Article.objects.filter(user=user) 
    24         .extra(select={"create_time_ym": "strftime('%%Y/%%m',create_time)"}) 
    25         .values("create_time_ym") 
    26         .annotate(c=Count("nid")).values_list("create_time_ym", "c")
    27 
    28     return {"cate_list": cate_list, "tag_list": tag_list, "date_list": date_list, "username": username}
    templatetags/my_tags
     1 import random
     2 
     3 
     4 def get_valid_img(request):
     5     def get_random_color():
     6         return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
     7 
     8     from io import BytesIO
     9     from PIL import Image, ImageDraw, ImageFont
    10     f = BytesIO()
    11 
    12     image = Image.new(mode='RGB', size=(120, 80), color=get_random_color())
    13     draw = ImageDraw.Draw(image)
    14     font = ImageFont.truetype('app01/static/fonts/kumo.ttf', size=36)
    15 
    16     temp = []
    17     for i in range(5):
    18         random_char = random.choice([str(random.randint(0, 9)),
    19                                      chr(random.randint(65, 90)),
    20                                      chr(random.randint(97, 122))
    21                                      ])
    22         draw.text((i * 24, 26), random_char, get_random_color(), font=font)
    23         temp.append(random_char)
    24 
    25     # width = 120
    26     # height = 80
    27     # for i in range(80):
    28     #     draw.point((random.randint(0,width),random.randint(0,height)),fill=get_random_color())
    29     #
    30     # for i in range(10):
    31     #     x1=random.randint(0,width)
    32     #     x2=random.randint(0,width)
    33     #     y1=random.randint(0,height)
    34     #     y2=random.randint(0,height)
    35     #     draw.line((x1,y1,x2,y2),fill=get_random_color())
    36     # for i in range(40):
    37     #     draw.point([random.randint(0, width), random.randint(0, height)], fill=get_random_color())
    38     #     x = random.randint(0, width)
    39     #     y = random.randint(0, height)
    40     #     draw.arc((x, y, x + 4, y + 4), 0, 90, fill=get_random_color())
    41     image.save(f, "png")
    42     data = f.getvalue()
    43 
    44     return data, temp
    utils/valid_code
     1 from django.contrib import admin
     2 
     3 # Register your models here.
     4 from .models import *
     5 
     6 admin.site.register(Article)
     7 admin.site.register(UserInfo)
     8 admin.site.register(Blog)
     9 admin.site.register(Tag)
    10 admin.site.register(Category)
    11 admin.site.register(Comment)
    12 admin.site.register(ArticleUpDown)
    13 admin.site.register(ArticleDetail)
    14 admin.site.register(Article2Tag)
    admin
     1 from django import forms
     2 from django.core.exceptions import ValidationError
     3 from django.forms import widgets
     4 from app01.models import *
     5 
     6 
     7 class RegisterForm(forms.Form):
     8     user = forms.CharField(max_length=18,
     9                            min_length=3,
    10                            error_messages={
    11                                'required': '不能为空',
    12                                'max_length': '用户名太长',
    13                                'min_length': '用户名太短'
    14                            },
    15                            widget=widgets.TextInput(attrs={"class": "form-control", "placeholder": "用户名"}))
    16     pwd = forms.CharField(max_length=18,
    17                           min_length=3,
    18                           error_messages={
    19                               'required': '不能为空',
    20                               'max_length': '密码太长',
    21                               'min_length': '密码太短'
    22                           },
    23                           widget=widgets.PasswordInput(attrs={"class": "form-control", "placeholder": "密码"}))
    24     repeat_pwd = forms.CharField(min_length=5, error_messages={"required": "该字段不能为空"},
    25                                  widget=widgets.PasswordInput(attrs={"class": "form-control", "placeholder": "确认密码"})
    26                                  )
    27     email = forms.EmailField(error_messages={"required": "该字段不能为空", "invalid": "格式错误"},
    28                              widget=widgets.EmailInput(attrs={"class": "form-control", "placeholder": "邮箱"})
    29                              )
    30 
    31     def clean_user(self):
    32         val = self.cleaned_data.get('user')
    33         ret = UserInfo.objects.filter(username=val)
    34         if not ret:
    35             return val
    36         else:
    37             raise ValidationError('该用户已经被注册!')
    38 
    39     def clean_tel(self):
    40         val = self.cleaned_data.get('tel')
    41         import re
    42         ret = re.search('1[356789]d{9}$', val)
    43         if ret:
    44             return val
    45         else:
    46             raise ValidationError('手机号格式错误')
    47 
    48     def clean(self):
    49         pwd = self.cleaned_data.get('pwd')
    50         repeat_pwd = self.cleaned_data.get('repeat_pwd')
    51         if pwd and repeat_pwd:
    52             if pwd == repeat_pwd:
    53                 return self.cleaned_data
    54             else:
    55                 raise ValidationError('两次密码不一致')
    56         else:
    57             return self.cleaned_data
    forms
      1 from django.db import models
      2 
      3 # Create your models here.
      4 from django.contrib.auth.models import AbstractUser
      5 
      6 
      7 class UserInfo(AbstractUser):  # 用户信息
      8     nid = models.AutoField(primary_key=True)
      9     nickname = models.CharField(verbose_name='昵称', max_length=32)
     10     telephone = models.CharField(max_length=11, null=True, unique=True)
     11     avatar = models.FileField(upload_to='avatar_dir/', default='/avatar/default.png')
     12     create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
     13     blog = models.OneToOneField(to='Blog', to_field='nid', null=True)
     14 
     15     def __str__(self):
     16         return self.username
     17 
     18 
     19 class Blog(models.Model):  # 博客信息
     20     nid = models.AutoField(primary_key=True)
     21     title = models.CharField(verbose_name="个人博客标题", max_length=64)
     22     site = models.CharField(verbose_name="个人博客后缀", max_length=32, unique=True)
     23     theme = models.CharField(verbose_name="博客主题", max_length=32)
     24 
     25     def __str__(self):
     26         return self.title
     27 
     28 
     29 class Category(models.Model):  # 博主个人文章分类表
     30     nid = models.AutoField(primary_key=True)
     31     title = models.CharField(verbose_name='分类标题', max_length=32)
     32     blog = models.ForeignKey(verbose_name='所属博客', to='Blog', to_field="nid")
     33 
     34     def __str__(self):
     35         return self.title
     36 
     37 
     38 class Tag(models.Model):
     39     nid = models.AutoField(primary_key=True)
     40     title = models.CharField(verbose_name="标签名称", max_length=32)
     41     blog = models.ForeignKey(verbose_name='所属博客', to='Blog', to_field='nid')
     42 
     43     def __str__(self):
     44         return self.title
     45 
     46 
     47 class Article(models.Model):
     48     nid = models.AutoField(primary_key=True)
     49     title = models.CharField(max_length=50, verbose_name='文章标题')
     50     desc = models.CharField(max_length=255, verbose_name='文章描述')
     51     create_time = models.DateTimeField(verbose_name='创建时间')
     52 
     53     comment_count = models.IntegerField(default=0)
     54     up_count = models.IntegerField(default=0)
     55     down_count = models.IntegerField(default=0)
     56 
     57     Category = models.ForeignKey(to= 'Category', to_field='nid', null=True)
     58     tags = models.ManyToManyField(
     59         to='Tag',
     60         through='Article2Tag',
     61         through_fields=('article', 'tag')
     62     )
     63     user = models.ForeignKey(verbose_name='作者', to='UserInfo', to_field='nid')
     64 
     65     def __str__(self):
     66         return self.title
     67 
     68 
     69 class ArticleDetail(models.Model):
     70     nid = models.AutoField(primary_key=True)
     71     content = models.TextField()
     72 
     73     article = models.OneToOneField(to='Article', to_field='nid')
     74 
     75 
     76 class ArticleUpDown(models.Model):
     77     nid = models.AutoField(primary_key=True)
     78     user = models.ForeignKey('UserInfo', null=True)
     79     article = models.ForeignKey('Article', null=True)
     80     is_up = models.BooleanField(default=True)
     81 
     82     class Meta:
     83         unique_together = [('article', 'user'), ]
     84 
     85 
     86 class Article2Tag(models.Model):
     87     nid = models.AutoField(primary_key=True)
     88     article = models.ForeignKey(verbose_name='文章', to='Article', to_field='nid')
     89     tag = models.ForeignKey(verbose_name='标签', to='Tag', to_field='nid')
     90 
     91     class Meta:
     92         unique_together = [('article', 'tag'), ]
     93 
     94     def __str__(self):
     95         v = self.article.title + "-----" + self.tag.title
     96         return v
     97 
     98 
     99 class Comment(models.Model):
    100     nid = models.AutoField(primary_key=True)
    101     article = models.ForeignKey(verbose_name='评论文章', to='Article', to_field='nid')
    102     user = models.ForeignKey(verbose_name='评论者', to='UserInfo', to_field='nid')
    103     content = models.CharField(verbose_name='评论内容', max_length=255)
    104     create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
    105 
    106     parent_comment = models.ForeignKey('self', null=True)
    107 
    108     def __str__(self):
    109         return self.content
    models
     1 from django.conf.urls import url, include
     2 from app01 import views
     3 
     4 urlpatterns = [
     5     #  文章详细页的点赞和评论
     6     url(r'^digg/$', views.digg),
     7     url(r'^comment/$',views.comment),
     8     url(r'^get_comment_tree/(d+)/$',views.get_comment_tree),
     9 
    10 
    11     url(r'^(?P<username>w+)/backend/$',views.backend),
    12     url(r'^(?P<username>w+)/backend_add_article/$',views.backend_add_article),
    13 
    14     # 个人站点的url配置
    15     url(r'^(?P<username>w+)/articles/(?P<article_id>d+).html/$', views.article_detail),
    16     url(r'^(?P<username>w+)/$', views.home_site),
    17     url(r'^(?P<username>w+)/(?P<condition>cate|tag|date)/(?P<params>(w+/?w+))$', views.home_site),
    18 ]
    url
      1 from django.shortcuts import render, HttpResponse, redirect
      2 from .models import *
      3 from .models import UserInfo
      4 from app01.forms import RegisterForm
      5 from django.contrib import auth
      6 from django.db.models import F
      7 from django.db import transaction
      8 from django.http import JsonResponse
      9 import json
     10 
     11 
     12 # 登录页
     13 def log_in(request):
     14     if request.is_ajax():
     15         user = request.POST.get("user")
     16         pwd = request.POST.get("pwd")
     17         valid_code = request.POST.get("valid_code")
     18         code_str = request.session.get("random_code_str")
     19         # 构造返回给前端的字典
     20         login_response = {"user": None, "error_msg": ""}
     21 
     22         if valid_code.upper() == code_str.upper():
     23             user = auth.authenticate(username=user, password=pwd)
     24             if user:
     25                 login_response["user"] = user.username
     26                 auth.login(request, user)
     27             else:
     28                 login_response["error_msg"] = "username or password error!"
     29         else:
     30             login_response["error_msg"] = "valid code error!"
     31         return HttpResponse(json.dumps(login_response))
     32 
     33     return render(request, "login.html")
     34 
     35 
     36 # 主页
     37 def index(request):
     38     username = request.user
     39     article_list = Article.objects.all()
     40     return render(request, 'index.html', locals())
     41 
     42 
     43 # 退出登录
     44 def logout(request):
     45     auth.logout(request)
     46     # return HttpResponse('OK')
     47     return redirect('/login/')
     48 
     49 
     50 # 注册页
     51 def register(request):
     52     # if request.method == "POST":
     53     if request.is_ajax():
     54         register_form = RegisterForm(request.POST)  # 接收前端ajax传过来的对象
     55         reg_response = {"user": None, "error_msg": None}  # 定义返回给前端的数据格式
     56         if register_form.is_valid():
     57             user = register_form.cleaned_data.get("user")
     58             pwd = register_form.cleaned_data.get("pwd")
     59             email = register_form.cleaned_data.get("email")
     60             avatar_obj = request.FILES.get('avatar')  # 图片对象
     61             if avatar_obj:
     62                 user_obj = UserInfo.objects.create_user(username=user, password=pwd, email=email, avatar=avatar_obj)
     63             else:
     64                 user_obj = UserInfo.objects.create_user(username=user, password=pwd, email=email)
     65             reg_response["user"] = user_obj.username
     66         else:
     67             reg_response["error_msg"] = register_form.errors
     68         return HttpResponse(json.dumps(reg_response))
     69 
     70     register_form = RegisterForm()
     71     return render(request, "register.html", {"register_form": register_form})
     72 
     73 
     74 # 验证码
     75 def get_valid_img(request):
     76     '''
     77     :param request:
     78     :get_valid_img: 生成验证码,返回图片数据
     79     :return:
     80     '''
     81 
     82     from app01.utils.valid_code import get_valid_img
     83     info = get_valid_img(request)
     84 
     85     request.session["random_code_str"] = "".join(info[1])
     86     '''
     87        if cookie.get(sesssion):更新
     88 
     89        1 生成随机字符串
     90        2 响应set_cookie {"sessionId":"123456abc"}
     91        3 在django-session表中插入一条记录
     92           session-key   session-data
     93           123456abc      {"random_code_str":"abc12"}
     94        '''
     95 
     96     return HttpResponse(info[0])
     97 
     98 
     99 # 修改密码
    100 def change_pwd(request):
    101     if request.method == 'POST':
    102         user = request.user.username
    103         old_pwd = request.POST.get('old_pwd')
    104         new_pwd = request.POST.get('new_pwd')
    105 
    106         # 构造返回给前端的字典
    107         change_response = {"flag": False}
    108         user_obj = auth.authenticate(username=user, password=old_pwd)
    109         if user_obj:
    110             if new_pwd == "":
    111                 change_response["error_msg"] = "新密码不能为空"
    112             else:
    113                 user_obj.set_password(new_pwd)
    114                 user_obj.save()
    115                 logout(request)
    116                 change_response['flag'] = True
    117         else:
    118             change_response["error_msg"] = "旧密码错误"
    119         return HttpResponse(json.dumps(change_response))
    120     return render(request, "change_pwd.html")
    121 
    122 
    123 # 个人主页
    124 def home_site(request, username, **kwargs):
    125     # 判断用户是否存在
    126     user = UserInfo.objects.filter(username=username).first()
    127     if not user:
    128         return render(request, "blog/not_found.html")
    129     blog = user.blog  # 当前站点
    130 
    131     if not kwargs:
    132         # 筛选当前站点的所有文章
    133         article_list = Article.objects.filter(user=user)
    134     else:
    135         # 归档跳转标签的请求,对article_list过滤
    136         condition = kwargs.get("condition")
    137         params = kwargs.get("params")
    138         if condition == "cate":
    139             article_list = Article.objects.filter(user=user).filter(Category__title=params)
    140         elif condition == "tag":
    141             article_list = Article.objects.filter(user=user).filter(tags__title=params)
    142         else:
    143             year, month = params.split("/")
    144             article_list = Article.objects.filter(user=user).filter(create_time__year=year, create_time__month=month)
    145     return render(request, "blog/home_site.html", locals())
    146 
    147 
    148 # 文章详细页
    149 def article_detail(request, username, article_id):
    150     article_obj = Article.objects.filter(pk=article_id).first()
    151     comment_list = Comment.objects.filter(article_id=article_id)
    152     return render(request, "blog/article_detail.html",
    153                   {"username": username, "article_obj": article_obj, "comment_list": comment_list})
    154 
    155 
    156 # 点赞
    157 def digg(request):
    158     article_id = request.POST.get("article_id")
    159     is_up = json.loads(request.POST.get("is_up"))
    160     user_id = request.user.pk
    161     response = {"state": True}
    162     try:
    163         with transaction.atomic():  # 事务
    164             obj = ArticleUpDown.objects.create(user_id=user_id, article_id=article_id, is_up=is_up)
    165             if is_up:
    166                 Article.objects.filter(pk=article_id).update(up_count=F("up_count") + 1)
    167             else:
    168                 Article.objects.filter(pk=article_id).update(down_count=F("down_count") + 1)
    169     except Exception as e:
    170         first_updown = ArticleUpDown.objects.filter(user_id=user_id, article_id=article_id).values("is_up").first().get(
    171             "is_up")
    172         response["state"] = False
    173         response["first_updown"] = first_updown
    174 
    175     return JsonResponse(response)
    176 
    177 
    178 # 评论
    179 def comment(request):
    180     content = request.POST.get("content")
    181     article_id = request.POST.get("article_id")
    182     user_id = request.user.pk
    183     pid = request.POST.get("pid")
    184 
    185     comment_response = {}
    186     with transaction.atomic():
    187         if pid:  # 子评论
    188             comment = Comment.objects.create(content=content, article_id=article_id, user_id=user_id,
    189                                              parent_comment_id=pid)
    190         else:
    191             comment = Comment.objects.create(content=content, article_id=article_id, user_id=user_id)
    192         Article.objects.filter(pk=article_id).update(comment_count=F("comment_count") + 1)
    193 
    194         comment_response["create_time"] = comment.create_time.strftime("%Y-%m-%d %H:%M")
    195         comment_response["content"] = comment.content
    196     return HttpResponse(json.dumps(comment_response))
    197 
    198 
    199 # 管理
    200 def backend(request, username):
    201     article_list = Article.objects.filter(user__username=username)
    202     return render(request, "blog/backend_index.html", {"username": username, "article_list": article_list})
    203 
    204 
    205 # 管理后台添加文章
    206 def backend_add_article(request, username):
    207     if request.method == "POST":
    208         content = request.POST.get("content")
    209 
    210         # 用BeautifulSoup过滤content
    211         valid_tags_attrs_list = {
    212             "div": ["id", "class", "style"],
    213             "img": ["src", "width", "height"],
    214             "a": ["href"],
    215             "p": [],
    216         }
    217         from bs4 import BeautifulSoup
    218         soup = BeautifulSoup(content, "html.parser")
    219         tags_list = soup.find_all()
    220 
    221         for tag in tags_list:
    222             if tag.name not in valid_tags_attrs_list:
    223                 tag.decompose()
    224         print("count:", soup)
    225 
    226     return render(request, "blog/backend_add_article.html")
    227 
    228 
    229 #  编辑器上传文件
    230 def upload_file(request):
    231     print(request.FILES)
    232     # 保存上传到指定路径
    233     obj = request.FILES.get("upload_img")
    234 
    235     from django.core.files.uploadedfile import InMemoryUploadedFile
    236     from cnbolg import settings
    237     import os
    238     path = os.path.join(settings.MEDIA_ROOT, "article_imgs", obj.name)
    239     with open(path, "wb") as f_write:
    240         for chunk in obj.chunks():
    241             f_write.write(chunk)
    242 
    243     # 给本文编辑器返回json字符串
    244     upload_response = {
    245         "error": 0,
    246         "url": "/media/article_imgs/%s" % obj.name
    247     }
    248 
    249     return HttpResponse(json.dumps(upload_response))
    250 
    251 
    252 # 评论树
    253 def get_comment_tree(request, article_id):
    254     comment_list = list(
    255         Comment.objects.filter(article_id=article_id).values("nid", "content", "parent_comment_id", "user__username"))
    256     return JsonResponse(comment_list, safe=False)
    !!! views

    templates

      1 <!DOCTYPE html>
      2 <html lang="en">
      3 <head>
      4     <meta charset="UTF-8">
      5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
      6     <meta name="viewport" content="width=device-width, initial-scale=1">
      7     <title>YueNet</title>
      8     <link rel="stylesheet" href="/static/bs/css/bootstrap.css">
      9     <link rel="stylesheet" href="/static/css/index.css">
     10     <script src="/static/js/jquery-3.2.1.min.js"></script>
     11     <script src="/static/bs/js/bootstrap.js"></script>
     12 </head>
     13 <body>
     14 <!--顶部导航条-->
     15 <nav class="navbar navbar-inverse">
     16     <div class="container">
     17         <!-- Brand and toggle get grouped for better mobile display -->
     18         <div class="navbar-header">
     19             <button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
     20                     data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
     21                 <span class="sr-only"></span>
     22                 <span class="icon-bar"></span>
     23                 <span class="icon-bar"></span>
     24                 <span class="icon-bar"></span>
     25             </button>
     26             <a class="navbar-brand" href="#">YueNet</a>
     27         </div>
     28 
     29         <!-- Collect the nav links, forms, and other content for toggling -->
     30         <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
     31             <ul class="nav navbar-nav">
     32             </ul>
     33 
     34             {% if request.user.is_authenticated %}
     35                 <ul class="nav navbar-nav navbar-right">
     36                     <li><a href="#">
     37                         <span class="glyphicon glyphicon-user"></span>&nbsp;&nbsp;{{ request.user.username }}</a></li>
     38                     <li><a href="/logout/">退出</a></li>
     39                     <li class="dropdown">
     40                         <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
     41                            aria-expanded="false">我的博客 <span class="caret"></span></a>
     42                         <ul class="dropdown-menu">
     43                             <li><a href="/change_pwd/">修改密码</a></li>
     44                             <li><a href="#">我的设置</a></li>
     45                             <li><a href="#">我的收藏</a></li>
     46                             <li role="separator" class="divider"></li>
     47                             <li><a href="#">注销账号</a></li>
     48                         </ul>
     49                     </li>
     50                 </ul>
     51             {% else %}
     52                 <ul class="nav navbar-nav navbar-right">
     53                     <li><a href="/login/">登录</a></li>
     54                     <li><a href="/register/">注册</a></li>
     55                 </ul>
     56             {% endif %}
     57         </div><!-- /.navbar-collapse -->
     58     </div><!-- /.container-fluid -->
     59 </nav>
     60 
     61 <!--页面主体开始-->
     62 <div class="container-fluid">
     63     <div class="row">
     64         <!-- 左侧菜单 -->
     65         <div class="col-md-3">
     66             <div class="panel panel-primary">
     67                 <!-- Default panel contents -->
     68                 <div class="panel-heading">文章分类</div>
     69                 <div class="panel-body">
     70                     <p>...</p>
     71                 </div>
     72             </div>
     73             <div class="panel panel-success">
     74                 <!-- Default panel contents -->
     75                 <div class="panel-heading">推荐博客</div>
     76                 <div class="panel-body">
     77                     <p>...</p>
     78                 </div>
     79             </div>
     80             <div class="panel panel-danger">
     81                 <!-- Default panel contents -->
     82                 <div class="panel-heading">统计信息</div>
     83                 <div class="panel-body">
     84                     <p>...</p>
     85                 </div>
     86             </div>
     87         </div>
     88         <!-- 文章列表 -->
     89         <div class="col-md-6">
     90             <div class="article_list">
     91                 {% for article_obj in article_list %}
     92                     <div class="article_item">
     93                         <h4><a href="/blog/{{ article_obj.user.username }}/articles/{{ article_obj.pk }}.html">{{ article_obj.title }}</a></h4>
     94                         <div class="row">
     95                             <div class="col-md-2">
     96                                 <a href="/blog/{{ article_obj.user.username }}">
     97                                     <img src="{{ article_obj.user.avatar.url }}" alt="" width="70" height="70">
     98                                 </a>
     99                             </div>
    100                             <div class="desc">
    101                                 <p>{{ article_obj.desc }}</p>
    102                             </div>
    103                         </div>
    104                         <div class="small">
    105                             <a href="/blog/{{ article_obj.user.username }}">{{ article_obj.user.username }}</a>
    106                             <span>发布于</span>
    107                             <span>{{ article_obj.create_time|date:'Y-m-d H:i' }}</span>&nbsp;&nbsp;
    108                             <span class="glyphicon glyphicon-comment"></span>评论({{ article_obj.comment_count }})&nbsp;&nbsp;
    109                             <span class="glyphicon glyphicon-thumbs-up"></span>点赞({{ article_obj.up_count }})
    110                         </div>
    111                     </div>
    112                 {% endfor %}
    113             </div>
    114             <!-- 广告 -->
    115             <div class="col-md-3"></div>
    116         </div>
    117     </div>
    118 
    119 
    120 </body>
    121 </html>
    index
     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     6     <meta name="viewport" content="width=device-width, initial-scale=1">
     7     <link rel="stylesheet" href="/static/bs/css/bootstrap.css">
     8     <script src="/static/js/jquery-3.2.1.min.js"></script>
     9     <title>登录页</title>
    10 </head>
    11 
    12 <body>
    13 <h3>登录页面</h3>
    14 <div class="container">
    15     <div class="row">
    16         <div class="col-md-6 col-md-offset-3">
    17             <form>
    18                 {% csrf_token %}
    19                 <div class="form-group">
    20                     <label for="user">用户名</label>
    21                     <input type="text" class="form-control" id="user" placeholder="Username">
    22                 </div>
    23                 <div class="form-group">
    24                     <label for="pwd">密码</label>
    25                     <input type="password" class="form-control" id="pwd" placeholder="Password">
    26                 </div>
    27                 <div class="row">
    28                     <div class="col-md-6">
    29                         <div class="form-group">
    30                             <label for="valid_code">验证码</label>
    31                             <input type="text" class="form-control" id="valid_code" placeholder="验证码">
    32                         </div>
    33                     </div>
    34                     <div class="col-md-6">
    35                         <img id="valid_img" width="260" height="60" src="/get_valid_img/" alt="">
    36                     </div>
    37                 </div>
    38                 <input type="button" value="submit" class="btn btn-primary pull-right login_btn">
    39                 <span class="error"> </span>
    40             </form>
    41         </div>
    42     </div>
    43 </div>
    44 
    45 <script>
    46     $('.login_btn').click(function () {
    47 
    48         $.ajax({
    49             url: '',
    50             type: 'post',
    51             data: {
    52                 "csrfmiddlewaretoken": $("[name='csrfmiddlewaretoken']").val(),
    53                 'user': $('#user').val(),
    54                 'pwd': $('#pwd').val(),
    55                 'valid_code': $('#valid_code').val()
    56             },
    57 
    58             success: function (data) {
    59                 var login_response = JSON.parse(data);
    60                 console.log(login_response);
    61                 if (login_response.user) {       // 登录成功
    62                     location.href = '/index/'
    63                 }
    64                 else {          // 登录失败
    65                     $('.error').html(login_response.error_msg).css('color', 'red');
    66 
    67                     setTimeout(function () {
    68                         $('.error').html('')
    69                     }, 1000)
    70                 }
    71             }
    72         })
    73     });
    74     // 验证码点击刷新
    75     $("#valid_img").click(function () {
    76         $(this)[0].src += "?"
    77     })
    78 
    79 
    80 </script>
    81 </body>
    82 </html>
    login
      1 <!DOCTYPE html>
      2 <html lang="en">
      3 <head>
      4     <meta charset="UTF-8">
      5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
      6     <meta name="viewport" content="width=device-width, initial-scale=1">
      7     <title>注册页</title>
      8     <link rel="stylesheet" href="/static/bs/css/bootstrap.css">
      9     <script src="/static/js/jquery-3.2.1.min.js"></script>
     10 </head>
     11 <body>
     12 <h3>注册页</h3>
     13 
     14 <div class="container">
     15     <div class="row">
     16         <div class="col-md-6 col-md-offset-3">
     17             <form>
     18                 {% csrf_token %}
     19                 <div>
     20                     <label for="id_user">用户名</label>
     21                     {{ register_form.user }}
     22                     <span class="pull-right"></span>
     23                 </div>
     24                 <div class="form-group">
     25                     <label for="id_pwd">密码</label>
     26                     {{ register_form.pwd }}
     27                     <span class="pull-right"></span>
     28                 </div>
     29                 <div class="form-group">
     30                     <label for="id_repeat_pwd">确认密码</label>
     31                     {{ register_form.repeat_pwd }}
     32                     <span class="pull-right"></span>
     33                 </div>
     34                 <div class="form-group">
     35                     <label for="id_email">邮箱</label>
     36                     {{ register_form.email }}
     37                     <span class="pull-right"></span>
     38                 </div>
     39                 <div class="form-group">
     40                     <label for="avatar">
     41                         头像
     42                         <img id="avater_img" src='/static/img/default.png' alt="" width="60" height="60">
     43                     </label>
     44                     <input type="file" style="display: none;" id="avatar">
     45                     <input type="button" value="submit" class="btn btn-primary pull-right reg_btn"> <span
     46                         class="error"></span>
     47                 </div>
     48             </form>
     49         </div>
     50     </div>
     51 </div>
     52 
     53 <script>
     54     // 头像预览功能
     55     $("#avatar").change(function () {
     56         var choose_file = $(this)[0].files[0];
     57         var reader = new FileReader();
     58         reader.readAsDataURL(choose_file);
     59         reader.onload = function () {
     60             $("#avater_img").attr("src", this.result)
     61         }
     62     });
     63 
     64     // ajax提交数据
     65     $(".reg_btn").click(function () {
     66         var formdata = new FormData();
     67         formdata.append("user", $("#id_user").val());
     68         formdata.append("pwd", $("#id_pwd").val());
     69         formdata.append("repeat_pwd", $("#id_repeat_pwd").val());
     70         formdata.append("email", $("#id_email").val());
     71         formdata.append("avatar", $("#avatar")[0].files[0]);
     72         formdata.append("csrfmiddlewaretoken", $("[name='csrfmiddlewaretoken']").val());
     73 
     74         $.ajax({
     75             url: "",
     76             type: "post",
     77             data: formdata,
     78             contentType: false,
     79             processData: false,
     80             success: function (data) {
     81                 console.log(data);
     82                 data = JSON.parse(data);
     83                 if (data.user) {
     84                     location.href = "/login/"
     85                 }
     86                 else {
     87                     // 清空上次错误信息
     88                     $("form span").html("");
     89                     $(".form-group").removeClass("has-error");
     90 
     91                     // 显示当前错误信息
     92                     $.each(data.error_msg, function (field, error_info) {
     93                         console.log(field, error_info[0]);
     94                         $("#id_" + field).parent().addClass("has-error");
     95                         $("#id_" + field).next().html(error_info[0]).css("color", "red");
     96                         // 判断全局错误
     97                         if (field == "__all__") {
     98                             $("#id_repeat_pwd").next().html(error_info[0]).css("color", "red");
     99                             $("#id_repeat_pwd").parent().addClass("has-error");
    100                         }
    101                     });
    102                 }
    103             }
    104         })
    105     });
    106 
    107 </script>
    108 
    109 </body>
    110 </html>
    register
     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     6     <meta name="viewport" content="width=device-width, initial-scale=1">
     7     <title>修改密码</title>
     8     <link rel="stylesheet" href="/static/bs/css/bootstrap.css">
     9     <script src="/static/js/jquery-3.2.1.min.js"></script>
    10 </head>
    11 <body>
    12 <h3>修改密码</h3>
    13 <div class="container">
    14     <div class="row">
    15         <div class="col-md-6 col-md-offset-3">
    16             <form>
    17                 {% csrf_token %}
    18                 <div class="form-group">
    19                     <label for="user">当前用户</label>
    20                     <input type="text" class="form-control" id="user" placeholder={{ request.user }} disabled>
    21                 </div>
    22                 <div class="form-group">
    23                     <label for="pwd">当前密码</label>
    24                     <input type="password" class="form-control" id="old_password" placeholder="Old_Password">
    25                 </div>
    26                 <div class="form-group">
    27                     <label for="pwd">新设密码</label>
    28                     <input type="password" class="form-control" id="new_password" placeholder="New_Password">
    29                 </div>
    30                 <input type="button" value="submit" class="btn btn-primary pull-right change_btn">
    31                 <span class="error"> </span>
    32             </form>
    33         </div>
    34     </div>
    35 </div>
    36 
    37 <script>
    38     $('.change_btn').click(function () {
    39 
    40         $.ajax({
    41             url: '',
    42             type: 'post',
    43             data: {
    44                 "csrfmiddlewaretoken": $("[name='csrfmiddlewaretoken']").val(),
    45                 'old_pwd': $('#old_password').val(),
    46                 'new_pwd': $('#new_password').val()
    47             },
    48             success:function (data) {
    49                 var change_response=JSON.parse(data);
    50                 console.log(change_response);
    51                 console.log(change_response.flag);
    52                 if (change_response.flag){  // 修改密码成功
    53                     location.href = '/index/'
    54                 }
    55                 else{       // 修改密码失败
    56                     $('.error').html(change_response.error_msg).css("color","red");
    57                     setTimeout(function () {
    58                         $('.error').html('')
    59                     },1000)
    60                 }
    61             }
    62         })
    63     });
    64 </script>
    65 </body>
    66 </html>
    change_pwd

     blog

     1  <div class="left_region">
     2     <div class="panel panel-info">
     3         <!-- Default panel contents -->
     4         <div class="panel-heading">我的分类</div>
     5         <div class="panel-body">
     6             <p>
     7                 {% for category in cate_list %}
     8                     <p><a href="/blog/{{ username }}/cate/{{ category.0 }}">{{ category.0 }}({{ category.1 }})</a></p>
     9                 {% endfor %}
    10             </p>
    11         </div>
    12     </div>
    13     <div class="panel panel-success">
    14         <!-- Default panel contents -->
    15         <div class="panel-heading">标签</div>
    16         <div class="panel-body">
    17             <p>
    18                 {% for tag in tag_list %}
    19                     <p><a href="/blog/{{ username }}/tag/{{ tag.0 }}">{{ tag.0 }}({{ tag.1 }})</a></p>
    20                 {% endfor %}
    21 
    22             </p>
    23         </div>
    24     </div>
    25     <div class="panel panel-danger">
    26         <!-- Default panel contents -->
    27         <div class="panel-heading">日期归档</div>
    28         <div class="panel-body">
    29             {% for date in date_list %}
    30                 <p><a href="/blog/{{ username }}/date/{{ date.0 }}">{{ date.0 }}({{ date.1 }})</a></p>
    31             {% endfor %}
    32 
    33         </div>
    34     </div>
    35 </div>
    blog/archive
     1 {% load my_tags %}
     2 <!DOCTYPE html>
     3 <html lang="en">
     4 <head>
     5     <meta charset="UTF-8">
     6     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     7     <meta name="viewport" content="width=device-width, initial-scale=1">
     8     <link rel="stylesheet" href="/static/bs/css/bootstrap.css">
     9     <link rel="stylesheet" href="/static/css/article_detail.css">
    10     <script src="/static/js/jquery-3.2.1.min.js"></script>
    11     <script src="/static/bs/js/bootstrap.js"></script>
    12     <!--引入访问用户的博客样式-->
    13     <link rel="stylesheet" href="/static/css/theme/{{ username }}.css">
    14     <title>Title</title>
    15     <style>
    16         * {
    17             margin: 0;
    18             padding: 0;
    19         }
    20 
    21         body {
    22             margin-bottom: 50px;
    23         }
    24 
    25         .header p.title {
    26             color: #ffffff;
    27             font-family: 微软雅黑, 华文细黑, 黑体, Arial;
    28             font-size: 24px;
    29             float: left;
    30             margin-left: 15px;
    31         }
    32 
    33         .action {
    34             float: right;
    35             margin-right: 40px;
    36         }
    37 
    38         .action a {
    39             padding: 5px 8px;
    40             color: white;
    41             background-color: #5ab2ce;
    42             font-size: 12px;
    43             text-decoration: none;
    44             margin-left: 5px;
    45         }
    46 
    47 
    48     </style>
    49 </head>
    50 <body>
    51 <div class="header">
    52     <p class="title"><a href="/index/">{{ username }}</a></p>
    53     <div class="action">
    54         <a href="/index/">首页</a>
    55         <a href="">文章</a>
    56         <a href="">随笔</a>
    57         <a href="/blog/{{ request.user.username }}/backend">管理</a>
    58     </div>
    59 </div>
    60 
    61 <div class="container">
    62     <div class="row">
    63         <div class="col-md-3">
    64             {% get_archive_style username %}
    65         </div>
    66         <div class="col-md-8">
    67             {% block content %}
    68                 <div class="articles_region">
    69                     <div class="article_list">
    70                         {% for article_obj in article_list %}
    71                             <div class="article_item">
    72                                 <h4>
    73                                     <a href="/blog/{{ username }}/articles/{{ article_obj.pk }}.html">{{ article_obj.title }}</a>
    74                                 </h4>
    75                                 <div class="row">
    76                                     <div class="desc">
    77                                         <p>{{ article_obj.desc }}</p>
    78                                     </div>
    79                                 </div>
    80                                 <div class="small pull-right">
    81                                     <a href="">{{ article_obj.user.username }}</a>
    82                                     <span>发布于</span>
    83                                     <span>{{ article_obj.create_time|date:'Y-m-d H:i' }}</span>&nbsp;&nbsp;
    84                                     <span class="glyphicon glyphicon-comment"></span>评论({{ article_obj.comment_count }})&nbsp;&nbsp;
    85                                     <span class="glyphicon glyphicon-thumbs-up"></span>点赞({{ article_obj.up_count }})
    86                                 </div>
    87                                 <hr>
    88                             </div>
    89                         {% endfor %}
    90                     </div>
    91                 </div>
    92             {% endblock %}
    93         </div>
    94 
    95     </div>
    96 </div>
    97 
    98 </body>
    99 </html>
    blog/home_base
    1 {% extends "blog/home_base.html" %}
    blog/home_site
      1 <!--引入font-awesome图标-->
      2 <link rel="stylesheet" href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.css">
      3 
      4 {% extends "blog/home_base.html" %}
      5 
      6 {% block content %}
      7     <div class="article_info">
      8         <h4 class="text-center"><a>{{ article_obj.title }}</a></h4>
      9         {{ article_obj.articledetail.content|safe }}
     10     </div>
     11 
     12     <div id="green_channel">
     13         <a>好文要顶</a>
     14         <a>关注我</a>
     15         <a>收藏该文</a>
     16         <a>
     17             <i class="fa fa-weibo"></i>
     18         </a>
     19         <a>
     20             <i class="fa fa-weixin"></i>
     21         </a>
     22     </div>
     23     <!--点赞功能-->
     24     <div id="div_digg">
     25         <div class="diggit digg">
     26             <span class="diggnum" id="digg_count">{{ article_obj.up_count }}</span>
     27         </div>
     28         <div class="buryit digg">
     29             <span class="burynum" id="bury_count">{{ article_obj.down_count }}</span>
     30         </div>
     31         <div class="diggword" id="digg_tips"></div>
     32     </div>
     33 
     34     <p>&nbsp;&nbsp;</p>
     35     <p>&nbsp;&nbsp;</p>
     36     <p>&nbsp;&nbsp;</p>
     37     <!--评论树功能-->
     38     <p class="show_tree">评论树:</p>
     39     <div class="comment_tree">
     40     </div>
     41 
     42 
     43     <hr>
     44     <!--评论楼功能-->
     45     <div class="comment_show">
     46         <p>评论楼:</p>
     47         <ul class="comment_list list-group">
     48             {% for comment in comment_list %}
     49                 <li class="comment_item list-group-item">
     50                     <!--评论内容顶部-->
     51                     <div class="row">
     52                         <div style="margin-left:20px;">
     53                             <a>#{{ forloop.counter }}楼</a>
     54                             <span>{{ comment.create_time|date:'Y-m-d H:i' }}</span>
     55                             <span>{{ comment.user.username }}</span>
     56                             <div class="pull-right">
     57                                 <a class="reply_btn" comment_id="{{ comment.pk }}"
     58                                    comment_user="{{ comment.user.username }}">回复</a>
     59                             </div>
     60                         </div>
     61                     </div>
     62                     <!--若为子评论时显示的内容-->
     63                     {% if comment.parent_comment_id %}
     64                         <div class="row">
     65                             <div class="parent_comment_info col-md-offset-1 well">
     66                                 <a href="">@{{ comment.parent_comment.user.username }}</a>
     67                                 <span>{{ comment.parent_comment.content }}</span>
     68                             </div>
     69                         </div>
     70                     {% endif %}
     71 
     72                     <!--评论内容-->
     73                     <div class="row">
     74                         <div class="col-md-offset-1">
     75                             <p>{{ comment.content }}</p>
     76                         </div>
     77                     </div>
     78                 </li>
     79             {% endfor %}
     80         </ul>
     81     </div>
     82 
     83     <!--评论框-->
     84     <div class="comment">
     85         <p>
     86             昵称:<input type="text" id="tbCommentAuthor" class="author" disabled size="50"
     87                       value="{{ request.user.username }}">
     88         </p>
     89         <label for="">评论内容:</label>
     90         <p>
     91             <textarea name="" id="comment_area" cols="60" rows="10"></textarea>
     92         </p>
     93         <input type="button" class="btn btn-default" value="提交" id="comment_submit_btn">
     94     </div>
     95     <div class="login_user_info" username="{{ request.user.usernaame }}"></div>
     96 
     97 
     98 
     99 
    100     {% csrf_token %}
    101     <script>
    102         // 绑定提交点赞事件
    103         $(".digg").click(function () {
    104             if ("{{ request.user.username }}") {
    105                 var is_up = $(this).hasClass("diggit");
    106                 $.ajax({
    107                     url: "/blog/digg/",
    108                     type: "post",
    109                     data: {
    110                         article_id:{{ article_obj.pk }},
    111                         csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val(),
    112                         is_up: is_up
    113                     },
    114                     success: function (data) {
    115                         var error_info;
    116                         if (data.state) {
    117                             if (is_up) {
    118                                 var val = parseInt($("#digg_count").text()) + 1;
    119                                 $("#digg_count").text(val);
    120                             }
    121                             else {
    122                                 var val = parseInt($("#bury_count").text()) + 1;
    123                                 $("#bury_count").text(val);
    124                             }
    125                         }
    126                         else {
    127                             if (data.first_updown) {
    128                                 error_info = "已经点赞过"
    129                             } else {
    130                                 error_info = "已经反对过"
    131                             }
    132                             $("#digg_tips").html(error_info).css('color', "red");
    133                             setTimeout(function () {
    134                                 $("#digg_tips").html("")
    135                             }, 1000)
    136                         }
    137                     }
    138                 })
    139             } else {
    140                 alert("请登录")
    141             }
    142         });
    143 
    144         // 基于ajax绑定 提交评论 事件
    145         $("#comment_submit_btn").click(function () {
    146             // parent_comment_pk 区分 根评论和子评论
    147             var content = $("#comment_area").val();
    148 
    149             if (parent_comment_pk) {
    150                 var index = content.indexOf("
    ");
    151                 content = content.slice(index + 1);
    152             } else {
    153                 content = $("#comment_area").val();
    154             }
    155             // 清空输入框的内容
    156             $("#comment_area").val("");
    157 
    158             $.ajax({
    159                 url: "/blog/comment/",
    160                 type: "post",
    161                 data: {
    162                     content: content,
    163                     article_id: "{{ article_obj.pk }}",
    164                     csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val(),
    165                     pid: parent_comment_pk
    166                 },
    167                 success: function (data) {
    168                     // Ajax生成评论内容并显示
    169                     var data = JSON.parse(data);
    170 
    171                     var floor_count = $(".comment_list .comment_item").length + 1;
    172                     var create_time = data.create_time;
    173                     var username = $(".login_user_info").attr("username");
    174                     var content = data.content;
    175 
    176 
    177                     s = '<li class="comment_item list-group-item"><div class="row"> <div class="col-md-offset-1"> <a href="">#' + floor_count + '楼</a>&nbsp;&nbsp;<span>' + create_time + '</span>&nbsp;&nbsp;<span>' + username + '</span> <div class="pull-right"></div></div></div> <div class="row"> <div class="col-md-offset-1"> <p>' + content + '</p> </div> </div> </li>';
    178                     $(".comment_list").append(s)
    179                 }
    180             })
    181         });
    182 
    183 
    184         // 绑定回复事件
    185         var parent_comment_pk = "";
    186         $(".comment_item .reply_btn").click(function () {
    187             // 获取焦点
    188             $("#comment_area").focus();
    189             // 设置:@用户名
    190             var val = "@" + $(this).attr("comment_user") + "
    ";
    191             $("#comment_area").val(val);
    192             // 获取回复评论的主键值 以便插入数据库
    193             parent_comment_pk = $(this).attr("comment_id")
    194         });
    195 
    196         // 评论树功能请求comment_list
    197         $(".show_tree").click(function () {
    198             $.ajax({
    199                 url: "/blog/get_comment_tree/" +{{ article_obj.pk }},
    200                 success: function (data) {
    201                     var comment_list = data;
    202                     var comment_html = "";
    203                     $.each(comment_list, function (index, comment) {
    204                         var nid = comment.nid;
    205                         var content = comment.content;
    206                         var pid = comment.parent_comment_id;
    207                         var username = comment.user__username;
    208 
    209                         comment_html = '<div class="comment_item"><span>' + username + '</span>:&nbsp;&nbsp;<span class="content" tree_comment_id=' + nid + '>' + content + '</span></div>';
    210                         if (pid) {
    211                             $("[tree_comment_id=" + pid + "]").parent().append(comment_html);
    212                         }
    213                         else {
    214                             $(".comment_tree").append(comment_html);
    215                         }
    216                     })
    217                 }
    218             })
    219         })
    220     </script>
    221 
    222 {% endblock %}
    !!! blog/article_detail
     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     6     <meta name="viewport" content="width=device-width, initial-scale=1">
     7     <link rel="stylesheet" href="/static/bs/css/bootstrap.css">
     8     <link rel="stylesheet" href="/static/css/backend_index.css">
     9     <title>后台管理</title>
    10 </head>
    11 
    12 <body>
    13 <div class="header">
    14     <div class="title">{{ username }}</div>
    15 </div>
    16 
    17 <div class="container-fluid">
    18 
    19     <div class="row">
    20         <!--管理页面左侧-->
    21         <div class="col-md-3">
    22             <ul class="list-group">
    23                 <li class="list-group-item">
    24                     <a href="/blog/{{ request.user.username }}/backend_add_article">添加文章</a>
    25                 </li>
    26                 <li class="list-group-item">分类管理</li>
    27                 <li class="list-group-item">标签操作</li>
    28             </ul>
    29         </div>
    30         <!--管理页面主体-->
    31         <div class="col-md-9">
    32             <div class="con">
    33                 <table class="table table-strippen table-hover">
    34                     <thead>
    35                     <tr>
    36                         <th>文章标题</th>
    37                         <th>操作</th>
    38                         <th>操作</th>
    39                     </tr>
    40                     </thead>
    41                     <tbody>
    42                     {% for article in article_list %}
    43                         <tr>
    44                             <td>{{ article.title }}</td>
    45                             <td><a href="">编辑</a></td>
    46                             <td><a href="">删除</a></td>
    47                         </tr>
    48                     {% endfor %}
    49                     </tbody>
    50                 </table>
    51             </div>
    52         </div>
    53     </div>
    54 </div>
    55 
    56 </body>
    57 </html>
    blog/backend_index
     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     6     <meta name="viewport" content="width=device-width, initial-scale=1">
     7     <link rel="stylesheet" href="/static/bs/css/bootstrap.css">
     8     <link rel="stylesheet" href="/static/css/backend_index.css">
     9     <title>后台管理</title>
    10 </head>
    11 
    12 <body>
    13 <div class="header">
    14     <div class="title">{{ username }}</div>
    15 </div>
    16 
    17 <div class="container-fluid">
    18 
    19     <div class="row">
    20         <!--管理页面左侧-->
    21         <div class="col-md-3">
    22             <ul class="list-group">
    23                 <li class="list-group-item">
    24                     <a href="/blog/{{ request.user.username }}/backend_add_article">添加文章</a>
    25                 </li>
    26                 <li class="list-group-item">分类管理</li>
    27                 <li class="list-group-item">标签操作</li>
    28             </ul>
    29         </div>
    30         <!--管理页面主体-->
    31         <div class="col-md-9">
    32             <div class="con">
    33                 <table class="table table-strippen table-hover">
    34                     <thead>
    35                     <tr>
    36                         <th>文章标题</th>
    37                         <th>操作</th>
    38                         <th>操作</th>
    39                     </tr>
    40                     </thead>
    41                     <tbody>
    42                     {% for article in article_list %}
    43                         <tr>
    44                             <td>{{ article.title }}</td>
    45                             <td><a href="">编辑</a></td>
    46                             <td><a href="">删除</a></td>
    47                         </tr>
    48                     {% endfor %}
    49                     </tbody>
    50                 </table>
    51             </div>
    52         </div>
    53     </div>
    54 </div>
    55 
    56 </body>
    57 </html>
    blog/backend_add_article
     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     6     <meta name="viewport" content="width=device-width, initial-scale=1">
     7     <title>Title</title>
     8 </head>
     9 <body>
    10 
    11 <p><b>404.</b> 抱歉! 您访问的资源不存在!</p>
    12 <p class="d">请确认您输入的网址是否正确,如果问题持续存在,请发邮件至contact@cnblogs.com与我们联系。</p>
    13 <p><a href="/">返回网站首页</a></p>
    14 
    15 </body>
    16 </html>
    blog/not_found
  • 相关阅读:
    列举 spring 支持的事务管理类型?
    memcached 能够更有效地使用内存吗?
    Redis 集群方案什么情况下会导致整个集群不可用?
    详细描述一下 Elasticsearch 更新和删除文档的过程?
    Redis 常见性能问题和解决方案?
    如果有大量的 key 需要设置同一时间过期,一般需要注意什么?
    synchronized 和 ReentrantLock 的区别?
    Redis 支持的 Java 客户端都有哪些?官方推荐用哪个?
    memcached 最大的优势是什么?
    memcached 是原子的吗?
  • 原文地址:https://www.cnblogs.com/iyouyue/p/8511009.html
Copyright © 2011-2022 走看看