Django——实现最基础的评论功能(只有一级评论)

 我对评论功能的理解:

————————(1)数据库建一个评论的表

————————(2)前端建一个提交评论的form表单

————————(3)表单提交评论内容后写入到数据库评论表中

————————(4)将评论表的数据取出来展示到前端评论列表中

 

1、项目目录结构

Django——实现最基础的评论功能(只有一级评论)

 

 

2、路由

(1)总路由:

from django.contrib import admin
from django.urls import path,include

urlpatterns = [
    path(‘admin/‘, admin.site.urls),
    path(‘blog/‘,include(‘blog.urls‘))
]

  

(2)app路由:

from django.urls import path,re_path
from blog import views

urlpatterns = [
    path(‘‘,views.index),
    re_path(‘article_detail/(\d+)‘,views.article_detail)   # 传入文章ID参数
]

  

 

3、模型

from django.db import models
from django.contrib.auth.models import User

class Article(models.Model):
    title = models.CharField(max_length=70,verbose_name=‘文章标题‘)
    content = models.TextField(verbose_name=‘正文‘)
    author = models.ForeignKey(to=User,on_delete=models.DO_NOTHING,verbose_name=‘作者‘)
    created_time = models.DateTimeField(auto_now_add=True,verbose_name=‘发布时间‘)

    class Meta:
        db_table = ‘article‘
        verbose_name = ‘文章‘
        verbose_name_plural = verbose_name


class Comment(models.Model):
    article = models.ForeignKey(to=Article,on_delete=models.DO_NOTHING,verbose_name=‘文章‘)
    content = models.TextField(verbose_name=‘评论内容‘)
    author = models.ForeignKey(User,on_delete=models.DO_NOTHING,verbose_name=‘评论者‘)
    post_time = models.DateTimeField(auto_now_add=True,verbose_name=‘评论时间‘)

    class Meta:
        db_table = ‘comment‘
        verbose_name = ‘评论‘
        verbose_name_plural = verbose_name

  

4、视图函数

from django.shortcuts import render,HttpResponse,redirect
from django.core.paginator import Paginator
from blog.models import Article
from blog.models import Comment

def index(request):
    all_article_list = Article.objects.all()
    paginator = Paginator(all_article_list,10) #实例化分页器对象
    page = int(request.GET.get(‘page‘,1)) #获取页码数
    article_list_obj = paginator.page(page)  #获取当前页的分页对象
    article_list = article_list_obj.object_list #获取当前页的数据列表
    context = {
        ‘article_list‘: article_list,
        ‘paginator‘: paginator,
        ‘article_list_obj‘: article_list_obj
    }
    return render(request,‘blog/index.html‘,context=context)


def article_detail(request,article_id):
    if request.method == ‘GET‘:
        article = Article.objects.get(id=article_id)
        comment_list = Comment.objects.filter(article_id=article.id)
        context = {
            ‘article‘: article,
            ‘request‘: request,
            ‘comment_list‘: comment_list
        }
        return render(request,‘blog/article_detail.html‘,context=context)
    else:
        c_id = article_id
        c_author = request.user.id
        c_content = request.POST.get(‘content‘)
        Comment.objects.create(content=c_content,article_id=c_id,author_id=c_author)
        return redirect(‘/blog/article_detail/{}/‘.format(c_id))

  

5、模板HTML

(1)base.html

<!doctype html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
    <meta name="description" content="">
    <meta name="author" content="">
    <link rel="icon" href="https://cdn.jsdelivr.net/npm/@bootcss/v3.bootcss.com@1.0.14/favicon.ico">
    <link rel="canonical" href="https://getbootstrap.com/docs/3.4/examples/jumbotron/">

    <title>{% block title %}{% endblock %}</title>

    <!-- Bootstrap core CSS -->
    <link href="https://cdn.jsdelivr.net/npm/@bootcss/v3.bootcss.com@1.0.14/dist/css/bootstrap.min.css" rel="stylesheet">
    <!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
    <link href="https://cdn.jsdelivr.net/npm/@bootcss/v3.bootcss.com@1.0.14/assets/css/ie10-viewport-bug-workaround.css" rel="stylesheet">
    <!-- Custom styles for this template -->
    <link href="https://cdn.jsdelivr.net/npm/@bootcss/v3.bootcss.com@1.0.14/examples/jumbotron/jumbotron.css" rel="stylesheet">
    <!-- Just for debugging purposes. Don‘t actually copy these 2 lines! -->
    <!--[if lt IE 9]><script src="https://cdn.jsdelivr.net/npm/@bootcss/v3.bootcss.com@1.0.14/assets/js/ie8-responsive-file-warning.js"></script><![endif]-->
    <script src="https://cdn.jsdelivr.net/npm/@bootcss/v3.bootcss.com@1.0.14/assets/js/ie-emulation-modes-warning.js"></script>
    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
  </head>

  <body>
    <nav class="navbar navbar-inverse navbar-fixed-top">
      <div class="container">
        <div class="navbar-header">
          <a class="navbar-brand" href="/blog/">博客首页</a>
        </div>
        <div id="navbar" class="navbar-collapse collapse">
          <form class="navbar-form navbar-right">
            <div class="form-group">
              <input type="text" placeholder="Email" class="form-control">
            </div>
            <div class="form-group">
              <input type="password" placeholder="Password" class="form-control">
            </div>
            <button type="submit" class="btn btn-success">登录</button>
          </form>
        </div><!--/.navbar-collapse -->
      </div>
    </nav>
    <br>

    {% block content %}

    {% endblock %}



  </body>
</html>

  

(2)首页index.html

{% extends ‘base.html‘ %}

{% block title %}
    博客首页
{% endblock %}

{% block content %}
        <div class="container">
        <div class="row">
          <div class="el-col-md-12">

              <table class="table">   {# 文章列表 #}
                  <tr class="info">
                      <th>ID</th>
                      <th>标题</th>
                      <th>正文</th>
                      <th>正文</th>
                      <th>时间</th>
                  </tr>
                  {% for article in article_list %}
                      <tr class="active">
                          <td>{{ article.id }}</td>
                          <td><a href="/blog/article_detail/{{ article.id }}/">{{ article.title}}</a></td>
                          <td>{{ article.content|truncatechars:100}}</td>
                          <td>{{ article.created_time}}</td>
                          <td>{{ article.author.username}}</td>
                      </tr>
                  {% endfor %}
              </table>              {# 文章列表结束 #}

              <div>                 {# 分页块 #}
                <nav aria-label="Page navigation">
                  <ul class="pagination">
                      {% if article_list_obj.has_previous %}
                        <li>
                           <a href="/blog/?page={{ article_list_obj.previous_page_number }}" aria-label="Previous">
                             <span aria-hidden="true">?</span>
                           </a>
                        </li>
                      {% endif %}
                      {% for number in paginator.page_range %}
                        <li><a href="/blog/?page={{ number }}">{{ number }}</a></li>
                      {% endfor %}
                      {% if article_list_obj.has_next %}
                          <li>
                           <a href="/blog/?page={{ article_list_obj.next_page_number }}" aria-label="Next">
                             <span aria-hidden="true">?</span>
                           </a>
                        </li>
                      {% endif %}
                  </ul>
                </nav>
              </div>   {# 分页块结束 #}



          </div>
        </div>
    </div>
{% endblock %}

  

(3)文章详情article_detail.html

{% extends ‘base.html‘ %}

{% block title %}
    文章详情
{% endblock %}

{% block content %}
<div class="container">
    <div class="row">
        <div class="col-md-12">

            <div class="panel panel-primary">   {# 文章详情区域 #}
               <div class="panel-body">
                 {{ article.title }}
               </div>
                <div class="panel-body">
                 {{ article.content }}
               </div>
               <div class="panel-footer">{{ article.author }} {{ article.created_time }}</div>
            </div>   {# 文章详情区域结束 #}

            <div>
                <hr>
                <h4><b>评论</b></h4>
                <form action="" method="post">
                    <textarea class="form-control" rows="3" name="content"></textarea>
                    <br>
                    <button type="submit" class="btn btn-primary">提交</button>
                </form>
                <hr>

                <div class="panel panel-danger">
                    <div class="panel-body">评论列表</div>

                    <div>
                        {% for comment in comment_list %}
                            <div> {{ comment.content }}</div>
                            <div> {{ comment.post_time }} & {{ comment.author.username }}</div>
                            <hr>
                        {% endfor %}
                    </div>
                </div>

            </div>
        
        </div>
    </div>
</div>
{% endblock %}

  

6、效果

Django——实现最基础的评论功能(只有一级评论)

 

 

 

Django——实现最基础的评论功能(只有一级评论)

 

Django——实现最基础的评论功能(只有一级评论)

上一篇:第一周(8/30-9/5)


下一篇:人工智能是什么