diff --git a/myblog/blog/admin.py b/myblog/blog/admin.py index 940654e..86f4d15 100644 --- a/myblog/blog/admin.py +++ b/myblog/blog/admin.py @@ -17,14 +17,20 @@ class PostAdmin(admin.ModelAdmin): class SiteSettingsAdmin(admin.ModelAdmin): - list_display = ('summary_length',) - + # 保持所有字段在列表中显示,方便直接编辑 + list_display = ('id', 'summary_length', 'contact_email', 'contact_wechat', 'contact_linkedin', 'contact_github') + list_display_links = ('id',) + def has_add_permission(self, request): # 限制只能有一个站点设置实例 return not SiteSettings.objects.exists() + def has_delete_permission(self, request, obj=None): + # 禁止删除站点设置 + return False + # 注册自定义的PostAdmin admin.site.register(Post, PostAdmin) admin.site.register(Category) -admin.site.register(SiteSettings, SiteSettingsAdmin) \ No newline at end of file +admin.site.register(SiteSettings, SiteSettingsAdmin) diff --git a/myblog/blog/feeds.py b/myblog/blog/feeds.py new file mode 100644 index 0000000..478b2a9 --- /dev/null +++ b/myblog/blog/feeds.py @@ -0,0 +1,96 @@ +from django.contrib.syndication.views import Feed +from django.urls import reverse +from django.shortcuts import get_object_or_404 +from .models import Post, Category + + +class LatestPostsFeed(Feed): + title = "六桂流芳的com" + link = "/rss/" + description = "最新博客文章" + # 添加content_type使浏览器能正确显示RSS内容 + content_type = 'application/xml; charset=utf-8' + + def items(self): + return Post.objects.order_by('-publish_date')[:10] + + def item_title(self, item): + return item.title + + def item_description(self, item): + return item.get_markdown_content() + + def item_link(self, item): + return reverse('detail', args=[item.pk]) + + +# 添加分类RSS Feed +class CategoryPostsFeed(Feed): + # 添加content_type使浏览器能正确显示RSS内容 + content_type = 'application/xml; charset=utf-8' + + def get_object(self, request, category_id): + return get_object_or_404(Category, pk=category_id) + + def title(self, obj): + return f"六桂流芳的com - {obj.name}分类" + + def link(self, obj): + return reverse('category_feed', args=[obj.pk]) + + def description(self, obj): + return f"{obj.name}分类的最新博客文章" + + def items(self, obj): + return Post.objects.filter(category=obj).order_by('-publish_date')[:10] + + def item_title(self, item): + return item.title + + def item_description(self, item): + return item.get_markdown_content() + + def item_link(self, item): + return reverse('detail', args=[item.pk]) + + +# 添加最新RSS Feed (与全部的区别在于数量限制) +class RecentPostsFeed(Feed): + title = "六桂流芳的com - 最新文章" + link = "/rss/recent/" + description = "最新的博客文章" + # 添加content_type使浏览器能正确显示RSS内容 + content_type = 'application/xml; charset=utf-8' + + def items(self): + return Post.objects.order_by('-publish_date')[:20] + + def item_title(self, item): + return item.title + + def item_description(self, item): + return item.get_markdown_content() + + def item_link(self, item): + return reverse('detail', args=[item.pk]) + + +# 添加全部RSS Feed +class AllPostsFeed(Feed): + title = "六桂流芳的com - 全部文章" + link = "/rss/all/" + description = "全部博客文章" + # 添加content_type使浏览器能正确显示RSS内容 + content_type = 'application/xml; charset=utf-8' + + def items(self): + return Post.objects.order_by('-publish_date') + + def item_title(self, item): + return item.title + + def item_description(self, item): + return item.get_markdown_content() + + def item_link(self, item): + return reverse('detail', args=[item.pk]) \ No newline at end of file diff --git a/myblog/blog/migrations/0009_sitesettings_contact_email_and_more.py b/myblog/blog/migrations/0009_sitesettings_contact_email_and_more.py new file mode 100644 index 0000000..8895291 --- /dev/null +++ b/myblog/blog/migrations/0009_sitesettings_contact_email_and_more.py @@ -0,0 +1,33 @@ +# Generated by Django 5.1 on 2025-07-27 15:53 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('blog', '0008_sitesettings'), + ] + + operations = [ + migrations.AddField( + model_name='sitesettings', + name='contact_email', + field=models.EmailField(blank=True, help_text='联系邮箱', max_length=254, null=True), + ), + migrations.AddField( + model_name='sitesettings', + name='contact_github', + field=models.URLField(blank=True, help_text='GitHub链接', null=True), + ), + migrations.AddField( + model_name='sitesettings', + name='contact_linkedin', + field=models.URLField(blank=True, help_text='LinkedIn链接', null=True), + ), + migrations.AddField( + model_name='sitesettings', + name='contact_wechat', + field=models.CharField(blank=True, help_text='微信号', max_length=100, null=True), + ), + ] diff --git a/myblog/blog/models.py b/myblog/blog/models.py index b1d15a5..c3c81bd 100644 --- a/myblog/blog/models.py +++ b/myblog/blog/models.py @@ -22,7 +22,11 @@ class Category(models.Model): # 添加站点设置模型 class SiteSettings(models.Model): summary_length = models.IntegerField(default=50, help_text="文章摘要字符长度") - + contact_email = models.EmailField(blank=True, null=True, help_text="联系邮箱") + contact_wechat = models.CharField(max_length=100, blank=True, null=True, help_text="微信号") + contact_linkedin = models.URLField(blank=True, null=True, help_text="LinkedIn链接") + contact_github = models.URLField(blank=True, null=True, help_text="GitHub链接") + class Meta: verbose_name = "站点设置" verbose_name_plural = "站点设置" diff --git a/myblog/blog/templates/blog/contact.html b/myblog/blog/templates/blog/contact.html new file mode 100644 index 0000000..9422353 --- /dev/null +++ b/myblog/blog/templates/blog/contact.html @@ -0,0 +1,325 @@ + + + + + 联系我 - 六桂流芳的com + + + + +
+ +
+ +
+ + +
+
+

联系我

+
+ 如果您有任何问题或想与我交流,可以通过以下方式联系我: +
+ +
    + {% if site_settings.contact_email %} +
  • + 邮箱: + {{ site_settings.contact_email }} +
  • + {% endif %} + {% if site_settings.contact_wechat %} +
  • + 微信: + {{ site_settings.contact_wechat }} +
  • + {% endif %} + {% if site_settings.contact_linkedin %} +
  • + LinkedIn: + {{ site_settings.contact_linkedin }} +
  • + {% endif %} + {% if site_settings.contact_github %} +
  • + GitHub: + {{ site_settings.contact_github }} +
  • + {% endif %} +
+
+
+
+ + + + \ No newline at end of file diff --git a/myblog/blog/templates/blog/detail.html b/myblog/blog/templates/blog/detail.html index 6346848..3b4699b 100644 --- a/myblog/blog/templates/blog/detail.html +++ b/myblog/blog/templates/blog/detail.html @@ -15,14 +15,14 @@ max-width: 1200px; margin: 0 auto; padding: 20px; - / / 修改: 确保容器支持sticky定位 min-height: 100 vh; + min-height: 100vh; } .sidebar { width: 250px; padding-right: 20px; border-right: 1px solid #eee; - / / 修改: 添加侧边栏固定定位相关样式 position: -webkit-sticky; + position: -webkit-sticky; position: sticky; top: 20px; align-self: flex-start; @@ -159,12 +159,57 @@ background-color: white; padding: 5px 0; } + + /* 添加导航栏样式 */ + .top-nav { + background-color: #007cba; + padding: 10px 0; + margin-bottom: 20px; + } + + .nav-container { + max-width: 1200px; + margin: 0 auto; + padding: 0 20px; + } + + .nav-links { + list-style: none; + padding: 0; + margin: 0; + display: flex; + } + + .nav-links li { + margin-right: 20px; + } + + .nav-links li a { + color: white; + text-decoration: none; + padding: 8px 12px; + border-radius: 4px; + transition: background-color 0.3s; + } + + .nav-links li a:hover { + background-color: rgba(255, 255, 255, 0.2); + } - -
-

六桂流芳的com

+ +
+
diff --git a/myblog/blog/templates/blog/index.html b/myblog/blog/templates/blog/index.html index 02e5bd6..5702253 100644 --- a/myblog/blog/templates/blog/index.html +++ b/myblog/blog/templates/blog/index.html @@ -159,12 +159,57 @@ footer { } + + /* 添加导航栏样式 */ + .top-nav { + background-color: #007cba; + padding: 10px 0; + margin-bottom: 20px; + } + + .nav-container { + max-width: 1200px; + margin: 0 auto; + padding: 0 20px; + } + + .nav-links { + list-style: none; + padding: 0; + margin: 0; + display: flex; + } + + .nav-links li { + margin-right: 20px; + } + + .nav-links li a { + color: white; + text-decoration: none; + padding: 8px 12px; + border-radius: 4px; + transition: background-color 0.3s; + } + + .nav-links li a:hover { + background-color: rgba(255, 255, 255, 0.2); + } - -
-

六桂流芳的com

+ +
diff --git a/myblog/blog/templates/blog/rss.html b/myblog/blog/templates/blog/rss.html new file mode 100644 index 0000000..e7ec029 --- /dev/null +++ b/myblog/blog/templates/blog/rss.html @@ -0,0 +1,302 @@ + + + + + RSS订阅 - 六桂流芳的com + + + + + + +
+ + +
+
+

RSS订阅

+
+ RSS是一种用于发布经常更新的内容的网页格式。通过RSS阅读器,您可以订阅我们的内容,及时获取最新文章更新。 + 点击下面的链接可以在浏览器中查看RSS内容,使用RSS阅读器订阅时请复制链接地址。 +
+ + +
+
+
+ + + + \ No newline at end of file diff --git a/myblog/blog/urls.py b/myblog/blog/urls.py index 5b70b43..ce133ec 100644 --- a/myblog/blog/urls.py +++ b/myblog/blog/urls.py @@ -1,7 +1,16 @@ from django.urls import path from . import views +from .feeds import LatestPostsFeed, CategoryPostsFeed, RecentPostsFeed, AllPostsFeed urlpatterns = [ path('', views.index, name='index'), path('post//', views.detail, name='detail'), -] + # 添加RSS页面路由 + path('rss/page/', views.rss_page, name='rss_page'), + # 添加联系我页面路由 + path('contact/', views.contact_page, name='contact_page'), + path('rss/', LatestPostsFeed(), name='rss_feed'), + path('rss/category//', CategoryPostsFeed(), name='category_feed'), + path('rss/recent/', RecentPostsFeed(), name='recent_feed'), + path('rss/all/', AllPostsFeed(), name='all_feed'), +] \ No newline at end of file diff --git a/myblog/blog/views.py b/myblog/blog/views.py index bb3c23d..859b769 100644 --- a/myblog/blog/views.py +++ b/myblog/blog/views.py @@ -22,6 +22,7 @@ def index(request): site_settings = SiteSettings.objects.first() summary_length = site_settings.summary_length if site_settings else 50 except SiteSettings.DoesNotExist: + site_settings = None summary_length = 50 # 根据分类和搜索关键词筛选文章 @@ -53,11 +54,40 @@ def index(request): 'categories': categories, 'selected_category': category_id, 'query': query, - 'search_type': search_type + 'search_type': search_type, + 'site_settings': site_settings }) def detail(request, post_id): post = get_object_or_404(Post, pk=post_id) categories = Category.objects.all() # 获取所有分类用于侧边栏 - return render(request, 'blog/detail.html', {'post': post, 'categories': categories}) \ No newline at end of file + try: + site_settings = SiteSettings.objects.first() + except SiteSettings.DoesNotExist: + site_settings = None + return render(request, 'blog/detail.html', {'post': post, 'categories': categories, 'site_settings': site_settings}) + + +# 添加RSS页面视图 +def rss_page(request): + categories = Category.objects.all() + try: + site_settings = SiteSettings.objects.first() + except SiteSettings.DoesNotExist: + site_settings = None + return render(request, 'blog/rss.html', { + 'categories': categories, + 'site_settings': site_settings + }) + + +# 添加联系我页面视图 +def contact_page(request): + try: + site_settings = SiteSettings.objects.first() + except SiteSettings.DoesNotExist: + site_settings = None + return render(request, 'blog/contact.html', { + 'site_settings': site_settings + }) \ No newline at end of file