From c36c11c92170949d7c7b3a4253998d625c12f6cc Mon Sep 17 00:00:00 2001 From: IMMOSkipper Date: Thu, 4 Dec 2025 14:17:04 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=90=9C=E7=B4=A2=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E7=9B=B8=E5=85=B3=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- blog/models.py | 2 +- blog/views.py | 54 ++++++++ db.sqlite3 | Bin 0 -> 278528 bytes djangoblog/settings.py | 30 +++-- djangoblog/whoosh_cn_backend.py | 18 ++- templates/blog/tags/sidebar.html | 212 ++++++++++++++++++++++++++++++- templates/search/search.html | 46 +++++++ whoosh_index/_MAIN_0.toc | Bin 0 -> 923 bytes 8 files changed, 344 insertions(+), 18 deletions(-) create mode 100644 db.sqlite3 create mode 100644 whoosh_index/_MAIN_0.toc diff --git a/blog/models.py b/blog/models.py index 083788bb..fa33b02c 100644 --- a/blog/models.py +++ b/blog/models.py @@ -9,7 +9,7 @@ from django.utils.timezone import now from django.utils.translation import gettext_lazy as _ from mdeditor.fields import MDTextField -from uuslug import slugify +from slugify import slugify from djangoblog.utils import cache_decorator, cache from djangoblog.utils import get_current_site diff --git a/blog/views.py b/blog/views.py index 773bb756..bec44ed2 100644 --- a/blog/views.py +++ b/blog/views.py @@ -285,14 +285,68 @@ def get_queryset(self): class EsSearchView(SearchView): + def get_queryset(self): + queryset = super(EsSearchView, self).get_queryset() + + # 获取排序参数 + sort_by = self.request.GET.get('sort', 'relevance') + + # 根据排序参数对结果进行排序 + if sort_by == 'time': + # 按时间排序(最新在前) + queryset = queryset.order_by('-pub_date') + elif sort_by == 'views': + # 按浏览量排序(最多在前) + queryset = queryset.order_by('-views') + # 默认按相关性排序 + + return queryset + def get_context(self): paginator, page = self.build_page() + + # 获取当前排序参数 + sort_by = self.request.GET.get('sort', 'relevance') + + # 关键词高亮处理 + query = self.query + if query: + # 替换HTML特殊字符以避免XSS攻击 + query = query.replace('&', '&').replace('<', '<').replace('>', '>') + + # 创建正则表达式,不区分大小写 + import re + regex = re.compile(r'(' + re.escape(query) + r')', re.IGNORECASE) + + # 对搜索结果中的标题和摘要进行关键词高亮 + for result in page.object_list: + article = result.object + + # 高亮标题中的关键词 + if article.title: + article.title = regex.sub(r'\1', article.title) + + # 高亮摘要中的关键词 + if hasattr(article, 'excerpt') and article.excerpt: + article.excerpt = regex.sub(r'\1', article.excerpt) + + # 如果没有摘要,从正文中提取部分内容并高亮 + elif article.body: + # 提取前200个字符作为摘要 + excerpt = article.body[:200] + if len(article.body) > 200: + excerpt += '...' + + # 高亮摘要中的关键词 + article.excerpt = regex.sub(r'\1', excerpt) + context = { "query": self.query, "form": self.form, "page": page, "paginator": paginator, "suggestion": None, + "sort_by": sort_by, # 将当前排序参数传递到模板 } if hasattr(self.results, "query") and self.results.query.backend.include_spelling: context["suggestion"] = self.results.query.get_spelling_suggestion() diff --git a/db.sqlite3 b/db.sqlite3 new file mode 100644 index 0000000000000000000000000000000000000000..5ca15a3e2801f676251f564758b162cf21459afd GIT binary patch literal 278528 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 AYXATM literal 0 HcmV?d00001 diff --git a/djangoblog/settings.py b/djangoblog/settings.py index b755d24f..86f76323 100644 --- a/djangoblog/settings.py +++ b/djangoblog/settings.py @@ -52,7 +52,7 @@ def env_to_bool(env, default): 'django.contrib.staticfiles', 'django.contrib.sites', 'django.contrib.sitemaps', - 'mdeditor', + # 'mdeditor', 'haystack', 'blog', 'accounts', @@ -108,16 +108,10 @@ def env_to_bool(env, default): DATABASES = { 'default': { - 'ENGINE': 'django.db.backends.mysql', - 'NAME': os.environ.get('DJANGO_MYSQL_DATABASE') or 'djangoblog', - 'USER': os.environ.get('DJANGO_MYSQL_USER') or 'root', - 'PASSWORD': os.environ.get('DJANGO_MYSQL_PASSWORD') or 'root', - 'HOST': os.environ.get('DJANGO_MYSQL_HOST') or '127.0.0.1', - 'PORT': int( - os.environ.get('DJANGO_MYSQL_PORT') or 3306), - 'OPTIONS': { - 'charset': 'utf8mb4'}, - }} + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': BASE_DIR / 'db.sqlite3', + } +} # Password validation # https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators @@ -360,7 +354,9 @@ def env_to_bool(env, default): DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' +# 搜索引擎配置 if os.environ.get('DJANGO_ELASTICSEARCH_HOST'): + # 使用Elasticsearch作为搜索引擎 ELASTICSEARCH_DSL = { 'default': { 'hosts': os.environ.get('DJANGO_ELASTICSEARCH_HOST') @@ -371,6 +367,18 @@ def env_to_bool(env, default): 'ENGINE': 'djangoblog.elasticsearch_backend.ElasticSearchEngine', }, } +else: + # 默认使用Whoosh作为搜索引擎 + import os + HAYSTACK_CONNECTIONS = { + 'default': { + 'ENGINE': 'djangoblog.whoosh_cn_backend.WhooshEngine', + 'PATH': os.path.join(BASE_DIR, 'whoosh_index'), + }, + } + +# 自动更新搜索索引 +HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor' # Plugin System PLUGINS_DIR = BASE_DIR / 'plugins' diff --git a/djangoblog/whoosh_cn_backend.py b/djangoblog/whoosh_cn_backend.py index 04e3f7fd..aefb48bd 100644 --- a/djangoblog/whoosh_cn_backend.py +++ b/djangoblog/whoosh_cn_backend.py @@ -22,7 +22,21 @@ from haystack.utils import get_identifier, get_model_ct from haystack.utils import log as logging from haystack.utils.app_loading import haystack_get_model -from jieba.analyse import ChineseAnalyzer +import jieba +from whoosh.analysis import Tokenizer, Token + +class ChineseTokenizer(Tokenizer): + def __call__(self, text, **kwargs): + # 使用jieba分词 + words = jieba.cut(text) + for word in words: + token = Token() + token.text = word + yield token + +# 创建中文分词器实例 +ChineseAnalyzer = ChineseTokenizer() + from whoosh import index from whoosh.analysis import StemmingAnalyzer from whoosh.fields import BOOLEAN, DATETIME, IDLIST, KEYWORD, NGRAM, NGRAMWORDS, NUMERIC, Schema, TEXT @@ -186,7 +200,7 @@ def build_schema(self, fields): else: # schema_fields[field_class.index_fieldname] = TEXT(stored=True, analyzer=StemmingAnalyzer(), field_boost=field_class.boost, sortable=True) schema_fields[field_class.index_fieldname] = TEXT( - stored=True, analyzer=ChineseAnalyzer(), field_boost=field_class.boost, sortable=True) + stored=True, analyzer=ChineseAnalyzer, field_boost=field_class.boost, sortable=True) if field_class.document is True: content_field_name = field_class.index_fieldname schema_fields[field_class.index_fieldname].spelling = True diff --git a/templates/blog/tags/sidebar.html b/templates/blog/tags/sidebar.html index ecb6d201..2bd7fb2a 100755 --- a/templates/blog/tags/sidebar.html +++ b/templates/blog/tags/sidebar.html @@ -5,11 +5,174 @@ + + + + + + {% if extra_sidebars %} {% for sidebar in extra_sidebars %} @@ -40,7 +203,14 @@ {% endif %} + + +