瀏覽代碼

comment.py

CJ 1 年之前
父節點
當前提交
c5f5e5a835

+ 7 - 0
blog/admin.py

@@ -1,3 +1,10 @@
 from django.contrib import admin
 
+
 # Register your models here.
+class CommentAdmin(admin.ModelAdmin):
+    # 需要显示的字段信息
+    list_display = ('id', 'nick_name', 'website', 'email', 'comment')
+
+    # 设置哪些字段可以点击进入编辑界面,默认是第一个字段
+    list_display_links = ['nick_name']

+ 3 - 2
blog/controller/article.py

@@ -2,7 +2,6 @@ import json
 from datetime import datetime
 
 from django.contrib.auth.decorators import login_required
-from django.core import serializers
 from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
 from django.http import JsonResponse, HttpResponseRedirect
 from django.shortcuts import render
@@ -52,11 +51,13 @@ def show_article(request, pk):
                                                                'user__first_name', 'user_id',
                                                                'user__last_name', 'markdown_text', 'is_top',
                                                                'html_text').first()
+    comments = models.Comment.objects.filter(article_id=int(pk))
+
     from blog.views import get_record_and_tags
     result = get_record_and_tags()
 
     return render(request, 'blog.html', context={'article': article, 'records': result['records'],
-                                                 'tags': result['tags']})
+                                                 'tags': result['tags'], 'comments': comments})
 
 
 @login_required(login_url='/')

+ 46 - 0
blog/controller/comment.py

@@ -0,0 +1,46 @@
+import datetime
+
+from django.http import JsonResponse, HttpResponseRedirect
+
+from blog import models
+from system.error.ServerException import ServerException
+
+
+
+
+def add_comment(request):
+    if request.method == 'POST':
+        nick_name = request.POST.get("nick_name")
+        avatar = request.POST.get("avatar")
+        website = request.POST.get("website")
+        article_id = request.POST.get("article_id")
+        comment = request.POST.get('comment')
+        email = request.POST.get('email')
+        article = models.Article.objects.get(id=int(article_id))
+        if article is None:
+            return JsonResponse({"success": False, "message": "没有找到对应文章"}, safe=False)
+
+        def is_empty(val):
+            return val is None or val == ''
+
+        if is_empty(nick_name):
+            request.session['msg'] = "请填写昵称"
+            return HttpResponseRedirect('/article/' + article_id + '.html')  # 跳转到主界面
+
+        if is_empty(comment):
+            request.session['msg'] = "请填写评论内容"
+            return HttpResponseRedirect('/article/' + article_id + '.html')  # 跳转到主界面
+
+        if is_empty(email):
+            request.session['msg'] = "请填写Email"
+            return HttpResponseRedirect('/article/' + article_id + '.html')  # 跳转到主界面
+
+        request.session['msg'] = ""
+        models.Comment.objects.create(nick_name=nick_name, avatar=avatar, article=article,
+                                                    website=website,
+                                                    comment=comment,
+                                                    created_time=datetime.datetime.now(), email=email)
+        return HttpResponseRedirect('/article/' + article_id + '.html')  # 跳转到主界面
+
+    else:
+        raise ServerException("错误的请求")

+ 0 - 62
blog/migrations/0001_initial.py

@@ -1,62 +0,0 @@
-# Generated by Django 4.2.3 on 2023-07-14 15:58
-
-from django.conf import settings
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
-    initial = True
-
-    dependencies = [
-        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
-    ]
-
-    operations = [
-        migrations.CreateModel(
-            name='Category',
-            fields=[
-                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('name', models.CharField(max_length=100, unique=True, verbose_name='分类')),
-            ],
-        ),
-        migrations.CreateModel(
-            name='FileRecord',
-            fields=[
-                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('origin_name', models.CharField(max_length=200, verbose_name='源文件名称')),
-                ('file_name', models.CharField(max_length=200, verbose_name='文件名称')),
-                ('file_path', models.FilePathField(max_length=255, verbose_name='文件路径')),
-                ('create_date', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
-                ('suffix', models.CharField(max_length=10, verbose_name='文件类型')),
-                ('file_net_path', models.CharField(max_length=200, verbose_name='文件网络路径')),
-            ],
-        ),
-        migrations.CreateModel(
-            name='Tags',
-            fields=[
-                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('name', models.CharField(max_length=100, unique=True, verbose_name='标签')),
-            ],
-        ),
-        migrations.CreateModel(
-            name='Article',
-            fields=[
-                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('title', models.CharField(max_length=70, verbose_name='标题')),
-                ('intro', models.TextField(blank=True, max_length=200, verbose_name='摘要')),
-                ('html_text', models.TextField(blank=True)),
-                ('markdown_text', models.TextField(blank=True)),
-                ('created_time', models.DateTimeField(auto_now_add=True, verbose_name='发布时间')),
-                ('type', models.SmallIntegerField(choices=[(1, 'ARTICLE'), (2, 'MUSIC'), (3, 'ESSAY'), (4, 'MEDIA')], default=1, verbose_name='类型')),
-                ('status', models.SmallIntegerField(choices=[(1, 'RELEASE'), (0, 'PADDING'), (-1, 'DELETE')], default=1, verbose_name='状态')),
-                ('is_top', models.BooleanField(default=True, verbose_name='是否在首页显示')),
-                ('category', models.ForeignKey(default='1', on_delete=django.db.models.deletion.CASCADE, to='blog.category', verbose_name='分类')),
-                ('cover', models.ForeignKey(blank=True, default='', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='cover', to='blog.filerecord', verbose_name='封面')),
-                ('music', models.ForeignKey(blank=True, default='', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='music', to='blog.filerecord', verbose_name='音乐路径')),
-                ('tags', models.ManyToManyField(blank=True, to='blog.tags')),
-                ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='作者')),
-            ],
-        ),
-    ]

+ 0 - 18
blog/migrations/0002_rename_is_show_index_article_is_top.py

@@ -1,18 +0,0 @@
-# Generated by Django 4.2.3 on 2023-07-15 02:26
-
-from django.db import migrations
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('blog', '0001_initial'),
-    ]
-
-    operations = [
-        migrations.RenameField(
-            model_name='article',
-            old_name='is_top',
-            new_name='is_top',
-        ),
-    ]

+ 0 - 18
blog/migrations/0003_category_seq.py

@@ -1,18 +0,0 @@
-# Generated by Django 4.2.3 on 2023-07-16 06:19
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('blog', '0002_rename_is_show_index_article_is_top'),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name='category',
-            name='seq',
-            field=models.IntegerField(default=1, verbose_name='排序'),
-        ),
-    ]

+ 21 - 3
blog/models.py

@@ -1,6 +1,9 @@
-from django.db import models
-from django.contrib.auth.models import User, AbstractUser
+from django.contrib import admin
 from django.contrib.auth import get_user_model as user_model
+from django.contrib.auth.models import User, AbstractUser
+from django.db import models
+
+from blog.admin import CommentAdmin
 
 # Create your models here.
 User = user_model()
@@ -16,7 +19,7 @@ class Category(models.Model):
     然后给name设置了一个'分类'的名称
     """
     name = models.CharField('分类', max_length=100, unique=True)
-    seq = models.IntegerField('排序',default=1)
+    seq = models.IntegerField('排序', default=1)
 
 
 class Tags(models.Model):
@@ -70,3 +73,18 @@ class Article(models.Model):
         (-1, "DELETE"))
     status = models.SmallIntegerField(verbose_name="状态", choices=status_choices, default=1)
     is_top = models.BooleanField(verbose_name="是否在首页显示", default=True)
+
+
+class Comment(models.Model):
+    article = models.ForeignKey(Article, on_delete=models.CASCADE, verbose_name='评论', default='1')
+    nick_name = models.CharField('昵称', max_length=100)
+    avatar = models.URLField('头像', max_length=255)
+    website = models.URLField('网址', max_length=100)
+    created_time = models.DateTimeField('创建时间', auto_now_add=True)
+    email = models.EmailField('Email', null=True, blank=True)
+    comment = models.TextField('评论', max_length=500, null=False, blank=False)
+
+
+admin.site.register(Comment, CommentAdmin)  # 注册模型 并 按照定制化的形式展示
+
+admin.site.site_title = 'CyberSick.net'  # 修改title

+ 0 - 0
blog/router/comment_url/__init__.py


+ 27 - 0
blog/router/comment_url/comment_url.py

@@ -0,0 +1,27 @@
+"""IBE URL Configuration
+
+The `urlpatterns` list routes URLs to views. For more information please see:
+    https://docs.djangoproject.com/en/3.2/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.contrib.staticfiles.urls import staticfiles_urlpatterns
+from django.urls import path
+from blog import views
+from blog.controller import comment
+
+urlpatterns = [
+    path('add', comment.add_comment),
+
+
+]
+urlpatterns += staticfiles_urlpatterns()

+ 5 - 0
blog/templatetags/day_util.py

@@ -19,3 +19,8 @@ def days_until(date):
     elif (day / 30) >= 1:
         return str(int((day / 30))) + '个月前'
     return str(day) + '天前'
+
+
+@register.filter
+def get_avatar(name):
+    return f'https://semantic-ui.com/images/avatar/small/{name}.jpg'

+ 5 - 0
blog/templatetags/page_tag.py

@@ -41,3 +41,8 @@ def circle_page_index(curr_page, loop_page):
         return format_html(page_ele)
     else:
         return ''
+
+
+@register.simple_tag
+def find_string(value:str, arg:str):
+    return value.find(arg) > -1

+ 1 - 0
system/urls.py

@@ -32,6 +32,7 @@ urlpatterns = [
     path('index', views.index),
     path('category/', include('blog.router.category_url.category_url')),
     path('article/', include('blog.router.article_url.article_url')),
+    path('comment/', include('blog.router.comment_url.comment_url')),
     path('search', views.search),
     path('date/<date>', views.current_record),
 

+ 121 - 0
templates/blog.html

@@ -211,7 +211,106 @@
             {% autoescape off %}
                 {{ article.html_text }}
             {% endautoescape %}
+            <h3 class="ui dividing header" style="margin-top: 10vh">评论</h3>
+            <div class="ui comments">
+                {% for comment in comments %}
+                    <div class="comment">
+                        <a class="avatar">
+                            <img src="{{ comment.avatar | get_avatar }}">
+                        </a>
+                        <div class="content">
+                            <a target="_blank" href="{{ comment.website }}" class="author">{{ comment.nick_name }}</a>
+                            <div class="text">{{ comment.comment }}</div>
+                            <div class="actions">
+                                <a href="mailto:{{ comment.email }}"> <i class="mail icon"></i>联系他</a>
+                                <a>
+                                    <i class="time icon"></i>
+                                    {{ comment.created_time }}
+                                </a>
+                            </div>
+                        </div>
+                    </div>
+
+                {% endfor %}
+
+            </div>
 
+            <form onsubmit="save()" method="post" action="/comment/add" id="comment_form" style="margin-top: 10px"
+                  class="ui form">
+                {% csrf_token %}
+                <input hidden="hidden" name="article_id" value="{{ article.id }}">
+                <h4 class="ui dividing header">发表评论</h4>
+
+                <div class="field">
+                    <div class="two fields">
+                        <div class="field">
+                            <label>昵称<span style="color: red">*</span></label>
+                            <input id="nick_name" type="text" name="nick_name" placeholder="昵称">
+                        </div>
+                        <div class="field">
+                            <label>Email<span style="color: red">*</span></label>
+                            <input id="email" type="email" name="email" placeholder="Email">
+                        </div>
+                    </div>
+                </div>
+                <div class="field">
+                    <div class="two fields">
+                        <div class="twelve wide field">
+                            <label>网站(可不填)</label>
+                            <input id="website" type="url" name="website" placeholder="网站">
+                        </div>
+                        <div class="four wide field">
+                            <label>头像<span style="color: red">*</span></label>
+                            <div class="ui fluid selection dropdown">
+                                <input value="jenny" type="hidden" name="avatar">
+                                <i class="dropdown icon"></i>
+                                <div class="default text">
+                                    Jenny Hess
+                                </div>
+                                <div class="menu">
+                                    <div class="item" data-value="jenny">
+                                        <img class="ui mini avatar image"
+                                             src="https://semantic-ui.com/images/avatar/small/jenny.jpg">
+                                        Jenny Hess
+                                    </div>
+                                    <div class="item" data-value="elliot">
+                                        <img class="ui mini avatar image"
+                                             src="https://semantic-ui.com/images/avatar/small/elliot.jpg">
+                                        Elliot Fu
+                                    </div>
+                                    <div class="item" data-value="stevie">
+                                        <img class="ui mini avatar image"
+                                             src="https://semantic-ui.com/images/avatar/small/stevie.jpg">
+                                        Stevie Feliciano
+                                    </div>
+                                    <div class="item" data-value="christian">
+                                        <img class="ui mini avatar image"
+                                             src="https://semantic-ui.com/images/avatar/small/christian.jpg">
+                                        Christian
+                                    </div>
+                                    <div class="item" data-value="matt">
+                                        <img class="ui mini avatar image"
+                                             src="https://semantic-ui.com/images/avatar/small/matt.jpg">
+                                        Matt
+                                    </div>
+                                    <div class="item" data-value="justen">
+                                        <img class="ui mini avatar image"
+                                             src="https://semantic-ui.com/images/avatar/small/justen.jpg">
+                                        Justen Kitsune
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <div class="field">
+                    <textarea name="comment" placeholder="评论"></textarea>
+                </div>
+                <div style="color: red">{{ msg }}</div>
+                <button class="ui blue labeled submit icon button">
+                    <i class="icon edit"></i> 提交
+                </button>
+            </form>
 
             <div class="ui hidden divider"></div>
         </div>
@@ -268,7 +367,29 @@
 <script src="{% static 'highlightjs/highlight.min.js' %}"></script>
 <script type="application/javascript" src="{% static 'photoswipe/photoswipe.umd.min.js' %}"></script>
 <script type="application/javascript" src="{% static 'photoswipe/photoswipe-lightbox.umd.min.js' %}"></script>
+<script>
+    restoreComment()
+
+    function restoreComment() {
+        if (localStorage.getItem('nick_name') !== undefined && localStorage.getItem('nick_name') !== '') {
+            $("#nick_name").val(localStorage.getItem('nick_name'))
+        }
+        if (localStorage.getItem('email') !== undefined && localStorage.getItem('email') !== '') {
+            $("#email").val(localStorage.getItem('email'))
+        }
+        if (localStorage.getItem('website') !== undefined && localStorage.getItem('website') !== '') {
+            $("#website").val(localStorage.getItem('website'))
+        }
+    }
 
+    function save() {
+        var data = $('#comment_form').serializeArray();
+        localStorage.setItem('nick_name', $('#nick_name').val())
+        localStorage.setItem('email', $('#email').val())
+        localStorage.setItem('website', $('#website').val())
+        return true
+    }
+</script>
 <script>
     $(document).ready(function () {
         $(".ui.toggle.button").click(function () {

+ 15 - 5
templates/index.html

@@ -2,6 +2,7 @@
 {% block css %}
     {% load avatar_tags %}
     {% load day_util %}
+    {% load page_tag %}
 
 {% endblock %}
 {% block container %}
@@ -45,11 +46,20 @@
                                             {{ item.user__first_name }}{{ item.user__last_name }}</a>
                                             发布了{{ item.category__name }}:<a
                                                     href="/article/{{ item.id }}.html">{{ item.title }}</a></div>
-                                        {% autoescape off %}
-                                            <div class="extra images">
-                                                {{ item.html_text }}
-                                            </div>
-                                        {% endautoescape %}
+                                        {% if '<iframe' in item.intro %}
+                                            {% autoescape off %}
+                                                <div class="extra images">
+                                                    {{ item.intro }}
+                                                </div>
+                                            {% endautoescape %}
+                                        {% else %}
+                                            {% autoescape off %}
+                                                <div class="extra images">
+                                                    {{ item.html_text }}
+                                                </div>
+                                            {% endautoescape %}
+                                        {% endif %}
+
 
                                     </div>