青少年编程与数学 02-009 Django 5 Web 编程 26课题、项目示例 ...

打印 上一主题 下一主题

主题 968|帖子 968|积分 2914

课题摘要: 本文是一份细致的Django博客应用开发指南,旨在帮助开发者构建功能全面的个人博客平台。文章起首先容了博客的基本概念、范例、平台和应用场景,强调了其在个人表达、互动性和内容多样性等方面的特点。接着,详细阐述了如何使用Django框架搭建博客应用,包括情况搭建、项目创建、模型定义、数据库迁移、视图编写、URL设置、模板创建等底子步骤。此外,还先容了如何添加用户认证、评论体系、文章分类、标签体系、搜刮功能、分页功能等高级特性。文章还涉及了定时任务、邮件通知、静态文件和媒体文件管理等实勤奋能的实现。末了,提供了摆设应用到生产情况的简朴指南,如使用Heroku举行摆设。这份指南为开发者提供了一个从零开始构建Django博客应用的完整路线图。
  
一、博客

博客(Blog)是“Weblog”的简称,是一种通常由个人管理、不定期张贴新的文章的网站。博客的内容通常根据日期反向排列,最新的文章排在最前面。博客可以包罗多种范例的内容,如文字、图片、视频、链接等。博客的重要特点包括:
1. 个人表达

博客是个人表达思想、观点和爱好的平台。博主(Bloger)可以通过博客分享生活点滴、专业知识、观光履历、读书笔记等,展示自己的个性和见解。
2. 互动性

博客通常具有评论功能,允许读者对文章举行评论和反馈,从而促进博主与读者之间的互动。这种互动性不仅增加了博客的意见意义性,还能帮助博主改进内容,提升写作程度。
3. 内容多样性

博客的内容可以非常多样化,涵盖各种主题和领域,如科技、时尚、美食、健康、教育、艺术等。差别的博主根据自己的爱好和专长,创作出各具特色的内容,满足差别读者的需求。
4. 更新频率

博客的更新频率因博主而异,有的博主每天更新,有的则每周或每月更新。更新频率的高低取决于博主的时间和精神,以及博客的主题和目标受众。
5. 自定义和个性化

博主可以对博客的外观和结构举行自定义,选择差别的主题、颜色方案、字体等,使博客具有独特的风格和个性。此外,还可以添加自定义的功能和插件,增强博客的功能性和用户体验。
6. 搜刮引擎优化(SEO)

博客内容通常具有较好的搜刮引擎优化结果,因为博客文章通常包罗丰富的关键词和高质量的内容。定期更新博客可以提高网站在搜刮引擎中的排名,吸引更多的流量。
7. 社交媒体集成

博客可以与社交媒体平台(如微博、微信、Facebook、Twitter 等)集成,方便博主将博客文章分享到社交媒体上,扩大文章的影响力和流传范围。同时,读者也可以通过社交媒体轻松地分享和推荐博客文章。
博客的范例

1. 个人博客

个人博客是最常见的博客范例,由个人创建和管理,重要用于分享个人生活、爱好爱好、学习和工作履历等。例如,一个观光博主大概会分享自己的观光照片和观光故事,一个美食博主大概会分享美食制作方法和餐厅推荐。
2. 专业博客

专业博客通常由行业专家或专业人士创建,专注于特定领域的知识和信息分享。例如,一个技能博主大概会分享编程技巧、软件评测、技能趋势等,一个医学博主大概会分享医疗知识、健康建议等。
3. 企业博客

企业博客由企业创建和管理,重要用于宣传企业产物和服务、分享行业动态、增强品牌影响力等。企业博客的内容通常包括产物先容、客户案例、行业分析、公司新闻等。
4. 团队博客

团队博客由多个成员共同管理,每个成员可以发布自己的文章。团队博客通常用于展示团队的工作结果、分享团队成员的专业知识和经验等。例如,一个软件开发团队的博客大概会包罗差别开发人员的技能分享和项目渴望。
博客的平台

1. 自建博客

自建博客须要自己搭建服务器、选择博客体系(如 WordPress、Django 等)、举行域名注册和网站备案等。自建博客具有高度的自由度和灵活性,但须要肯定的技能底子和维护成本。
2. 博客托管平台

博客托管平台(如 Blogger、WordPress.com、简书等)提供了便捷的博客创建和管理服务,用户无需自己搭建服务器和举行域名注册,只需注册账号即可开始创建博客。这些平台通常提供丰富的主题和插件,方便用户自定义博客的外观和功能。
博客的应用场景

1. 个品德牌建立

通过定期更新高质量的博客内容,可以提升个人在特定领域的知名度和影响力,建立个品德牌。例如,一个自由职业者可以通过博客展示自己的专业技能和项目经验,吸引潜在客户。
2. 知识分享

博客是分享知识和经验的绝佳平台,可以帮助他人解决标题,同时也能提升自己的专业程度。例如,一个教师可以通过博客分享教学经验和课程资料,帮助其他教师和学生。
3. 企业营销

企业可以通过博客发布产物信息、行业动态、客户案例等,吸引潜在客户,提高品牌知名度和用户粘性。例如,一个电商企业可以通过博客发布新品评测、优惠活动等,促进产物贩卖。
4. 社区建立

博客可以作为社区建立的一部分,通太过享内容和促进互动,吸引志同道合的人聚集在一起,形成一个活跃的社区。例如,一个拍照爱好者社区可以通过博客分享拍照技巧、作品展示等,促进成员之间的交流和相助。
总结

博客是一种多功能的在线平台,可以用于个人表达、知识分享、品牌建立和社区建立等多种场景。通过合理使用博客,可以提升个人和企业的影响力,增强用户互动,实现多种目标。
二、个人博客应用

个人博客应用是一种允许用户创建、发布和管理个人博客的软件或在线服务。它为用户提供了一个平台,可以用来分享生活点滴、专业知识、爱好爱好等。以下是一些常见的个人博客应用及其特点:
1. WordPress

WordPress 是一个功能强大的内容管理体系(CMS),广泛用于创建个人博客。它具有以下特点:


  • 高度可定制:提供丰富的主题和插件,用户可以根据自己的需求定制博客的外观和功能。
  • 用户友好:界面友好,易于使用,适合初学者和专业用户。
  • 强大的社区支持:拥有巨大的用户社区和丰富的文档,遇到标题时容易找到解决方案。
  • SEO 优化:提供多种 SEO 插件,帮助用户优化博客内容,提高搜刮引擎排名。
2. Blogger

Blogger 是一个由 Google 提供的免费博客平台,具有以下特点:


  • 免费使用:无需自己搭建服务器,注册账号即可开始创建博客。
  • 集成 Google 服务:与 Google 的其他服务(如 Google Analytics、Google Adsense)无缝集成,方便用户举行流量分析和广告投放。
  • 简朴易用:界面简便,利用简朴,适合初学者。
  • 丰富的模板:提供多种免费模板,用户可以轻松选择和定制。
3. Medium

Medium 是一个内容发布平台,具有以下特点:


  • 简便的界面:界面简便雅观,注重内容的展示,适合阅读。
  • 高质量内容:鼓励用户发布高质量、有深度的内容,吸引了大量专业作者和读者。
  • 社交功能:支持关注作者、点赞、评论和分享,促进用户之间的互动。
  • 自动排版:提供自动排版功能,用户无需担心排版标题,只需专注于内容创作。
4. Ghost

Ghost 是一个开源的博客平台,具有以下特点:


  • 简便优雅:界面简便,设计优雅,注重用户体验。
  • Markdown 支持:支持 Markdown 语法,适合技能博客和写作爱好者。
  • 高度可定制:提供丰富的主题和插件,用户可以根据自己的需求定制博客的外观和功能。
  • 强大的编辑器:提供功能强大的编辑器,支持富文本编辑和 Markdown 编辑。
5. Hexo

Hexo 是一个基于 Node.js 的静态博客框架,具有以下特点:


  • 生成静态页面:生成静态页面,加载速度快,适合摆设在静态文件托管服务上。
  • 高度可定制:提供丰富的主题和插件,用户可以根据自己的需求定制博客的外观和功能。
  • Markdown 支持:支持 Markdown 语法,适合技能博客和写作爱好者。
  • 灵活的摆设:支持多种摆设方式,如 GitHub Pages、Vercel 等。
6. Jekyll

Jekyll 是一个基于 Ruby 的静态博客框架,具有以下特点:


  • 生成静态页面:生成静态页面,加载速度快,适合摆设在静态文件托管服务上。
  • 高度可定制:提供丰富的主题和插件,用户可以根据自己的需求定制博客的外观和功能。
  • Markdown 支持:支持 Markdown 语法,适合技能博客和写作爱好者。
  • GitHub Pages 集成:与 GitHub Pages 无缝集成,摆设简朴,适合开源项目和个人博客。
7. Django 博客

Django 是一个功能强大的 Python Web 框架,可以用于创建高度定制的个人博客应用。具有以下特点:


  • 高度可定制:可以完全自定义博客的外观和功能,适合有开发本领的用户。
  • 强大的功能:支持用户认证、评论体系、SEO 优化等多种功能。
  • 安全可靠:Django 框架自己具有强大的安全机制,确保博客的安全性。
  • 灵活的摆设:支持多种摆设方式,如 Heroku、AWS、DigitalOcean 等。
8. Flask 博客

Flask 是一个轻量级的 Python Web 框架,可以用于创建简便的个人博客应用。具有以下特点:


  • 轻量级:框架轻量级,启动速度快,适合小型项目。
  • 高度可定制:可以完全自定义博客的外观和功能,适合有开发本领的用户。
  • 灵活的摆设:支持多种摆设方式,如 Heroku、AWS、DigitalOcean 等。
  • 易于上手:文档丰富,社区活跃,适合初学者学习和使用。
选择个人博客应用的建议


  • 技能本领:假如你有开发本领,可以选择 Django 或 Flask 等框架来自建博客;假如你没有开发本领,可以选择 WordPress、Blogger、Medium 等现成的平台。
  • 定制需求:假如你须要高度定制博客的外观和功能,可以选择 WordPress、Django、Flask 等;假如你对博客的外观和功能要求不高,可以选择 Blogger、Medium 等。
  • 内容范例:假如你重要发布技能文章,可以选择支持 Markdown 的博客平台,如 Ghost、Hexo、Jekyll 等;假如你重要发布生活点滴和图片,可以选择 WordPress、Blogger 等。
  • 社区和支持:选择一个有活跃社区和丰富文档的平台,可以在遇到标题时更容易找到解决方案。
通过以上先容,你可以根据自己的需求和偏好选择最适合的个人博客应用,开始你的博客之旅。
三、Django 博客

实现一个基于 Django 的博客应用涉及多个步骤,从项目搭建到功能实现,以下是一个基本的指南:
1. 情况搭建

起首,确保你的开发情况中已安装 Python 和 Django。假如未安装,可以通过以下命令安装 Django:
  1. pip install django
复制代码
2. 创建 Django 项目

创建一个新的 Django 项目,假设项目名为 myblog:
  1. django-admin startproject myblog
  2. cd myblog
复制代码
3. 创建博客应用

在项目目次下,创建一个新的应用,假设应用名为 blog:
  1. python manage.py startapp blog
复制代码
4. 设置应用

在 myblog/settings.py 中,添加 blog 应用到 INSTALLED_APPS:
  1. INSTALLED_APPS = [
  2.     # ...
  3.     'blog',
  4.     # ...
  5. ]
复制代码
5. 定义模型(Model)

在 blog/models.py 中定义博客文章的模型,例如:
  1. from django.db import models
  2. from django.contrib.auth.models import User
  3. class Post(models.Model):
  4.     title = models.CharField(max_length=200)
  5.     content = models.TextField()
  6.     date_posted = models.DateTimeField(auto_now_add=True)
  7.     author = models.ForeignKey(User, on_delete=models.CASCADE)
  8.     def __str__(self):
  9.         return self.title
复制代码
6. 数据库迁移

创建数据库表:
  1. python manage.py makemigrations
  2. python manage.py migrate
复制代码
7. 创建视图(View)

在 blog/views.py 中创建视图来处理请求和返反响应,例如:
  1. from django.shortcuts import render
  2. from .models import Post
  3. def home(request):
  4.     context = {
  5.         'posts': Post.objects.all()
  6.     }
  7.     return render(request, 'blog/home.html', context)
复制代码
8. 设置 URL

在 blog 应用目次下创建 urls.py 文件,并定义 URL 模式:
  1. # blog/urls.py
  2. from django.urls import path
  3. from . import views
  4. urlpatterns = [
  5.     path('', views.home, name='blog-home'),
  6. ]
复制代码
在项目标 urls.py 中包罗 blog 应用的 URL 设置:
  1. # myblog/urls.py
  2. from django.contrib import admin
  3. from django.urls import include, path
  4. urlpatterns = [
  5.     path('admin/', admin.site.urls),
  6.     path('blog/', include('blog.urls')),
  7. ]
复制代码
9. 创建模板

在 blog 应用目次下创建 templates/blog 文件夹,并创建 home.html 模板文件:
  1. <!-- blog/templates/blog/home.html -->
  2. {% extends "base_generic.html" %}
  3. {% block content %}
  4.     <h2>Blog Home</h2>
  5.     {% for post in posts %}
  6.         <article class="media content-section">
  7.             <div class="media-body">
  8.                 <div class="article-metadata">
  9.                     <a class="mr-2" href="#">{{ post.author }}</a>
  10.                     <small class="text-muted">{{ post.date_posted }}</small>
  11.                 </div>
  12.                 <h2><a class="article-title" href="#">{{ post.title }}</a></h2>
  13.                 <p class="article-content">{{ post.content }}</p>
  14.             </div>
  15.         </article>
  16.     {% endfor %}
  17. {% endblock content %}
复制代码
10. 运行开发服务器

启动 Django 开发服务器,查看应用:
  1. python manage.py runserver
复制代码
访问 http://127.0.0.1:8000/blog/ 查看博客首页。
11. 添加更多功能

根据须要,你可以添加更多功能,如用户认证、评论体系、文章分类、标签体系、搜刮功能等。
以上步骤提供了一个基本的框架,用于创建一个基于 Django 的博客应用。你可以根据自己的需求进一步扩展和定制应用。
四、博客应用示例

创建一个功能全面的 Django 博客应用项目涉及多个步骤,包括项目搭建、模型设计、视图编写、模板创建、URL 设置、用户认证、评论体系、文章分类和标签体系等。以下是一个详细的指南,帮助你创建一个完整的 Django 博客应用项目。
1. 情况搭建

确保你的开发情况中已安装 Python 和 Django。假如未安装,可以通过以下命令安装 Django:
  1. pip install django
复制代码
2. 创建 Django 项目

创建一个新的 Django 项目,假设项目名为 myblog:
  1. django-admin startproject myblog
  2. cd myblog
复制代码
3. 创建博客应用

在项目目次下,创建一个新的应用,假设应用名为 blog:
  1. python manage.py startapp blog
复制代码
4. 设置应用

在 myblog/settings.py 中,添加 blog 应用到 INSTALLED_APPS:
  1. INSTALLED_APPS = [
  2.     # ...
  3.     'blog',
  4.     # ...
  5. ]
复制代码
5. 定义模型(Model)

在 blog/models.py 中定义博客文章、分类和标签的模型:
  1. from django.db import models
  2. from django.contrib.auth.models import User
  3. from django.utils.text import slugify
  4. class Category(models.Model):
  5.     name = models.CharField(max_length=100)
  6.     def __str__(self):
  7.         return self.name
  8. class Tag(models.Model):
  9.     name = models.CharField(max_length=100)
  10.     def __str__(self):
  11.         return self.name
  12. class Post(models.Model):
  13.     title = models.CharField(max_length=200)
  14.     content = models.TextField()
  15.     date_posted = models.DateTimeField(auto_now_add=True)
  16.     author = models.ForeignKey(User, on_delete=models.CASCADE)
  17.     category = models.ForeignKey(Category, on_delete=models.CASCADE)
  18.     tags = models.ManyToManyField(Tag)
  19.     slug = models.SlugField(max_length=250, unique_for_date='date_posted')
  20.     def save(self, *args, **kwargs):
  21.         self.slug = slugify(self.title)
  22.         super(Post, self).save(*args, **kwargs)
  23.     def __str__(self):
  24.         return self.title
  25. class Comment(models.Model):
  26.     post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
  27.     name = models.CharField(max_length=80)
  28.     email = models.EmailField()
  29.     body = models.TextField()
  30.     created = models.DateTimeField(auto_now_add=True)
  31.     updated = models.DateTimeField(auto_now=True)
  32.     active = models.BooleanField(default=True)
  33.     class Meta:
  34.         ordering = ('created',)
  35.     def __str__(self):
  36.         return f'Comment by {self.name} on {self.post}'
复制代码
6. 数据库迁移

创建数据库表:
  1. python manage.py makemigrations
  2. python manage.py migrate
复制代码
7. 创建视图(View)

在 blog/views.py 中创建视图来处理请求和返反响应:
  1. from django.shortcuts import render, get_object_or_404
  2. from .models import Post, Comment
  3. from .forms import CommentForm
  4. def post_list(request):
  5.     posts = Post.objects.all().order_by('-date_posted')
  6.     return render(request, 'blog/post_list.html', {'posts': posts})
  7. def post_detail(request, year, month, day, post):
  8.     post = get_object_or_404(Post, slug=post, date_posted__year=year, date_posted__month=month, date_posted__day=day)
  9.     comments = post.comments.filter(active=True)
  10.     new_comment = None
  11.     if request.method == 'POST':
  12.         comment_form = CommentForm(data=request.POST)
  13.         if comment_form.is_valid():
  14.             new_comment = comment_form.save(commit=False)
  15.             new_comment.post = post
  16.             new_comment.save()
  17.     else:
  18.         comment_form = CommentForm()
  19.     return render(request, 'blog/post_detail.html', {'post': post, 'comments': comments, 'new_comment': new_comment, 'comment_form': comment_form})
复制代码
8. 创建表单(Form)

在 blog/forms.py 中创建评论表单:
  1. from django import forms
  2. class CommentForm(forms.ModelForm):
  3.     class Meta:
  4.         model = Comment
  5.         fields = ('name', 'email', 'body')
复制代码
9. 设置 URL

在 blog 应用目次下创建 urls.py 文件,并定义 URL 模式:
  1. # blog/urls.py
  2. from django.urls import path
  3. from . import views
  4. urlpatterns = [
  5.     path('', views.post_list, name='post_list'),
  6.     path('<int:year>/<int:month>/<int:day>/<slug:post>/', views.post_detail, name='post_detail'),
  7. ]
复制代码
在项目标 urls.py 中包罗 blog 应用的 URL 设置:
  1. # myblog/urls.py
  2. from django.contrib import admin
  3. from django.urls import include, path
  4. urlpatterns = [
  5.     path('admin/', admin.site.urls),
  6.     path('blog/', include('blog.urls')),
  7. ]
复制代码
10. 创建模板

在 blog 应用目次下创建 templates/blog 文件夹,并创建 post_list.html 和 post_detail.html 模板文件:
post_list.html

  1. <!-- blog/templates/blog/post_list.html -->
  2. {% extends "base_generic.html" %}
  3. {% block content %}
  4.     <h2>Blog Home</h2>
  5.     {% for post in posts %}
  6.         <article class="media content-section">
  7.             <div class="media-body">
  8.                 <div class="article-metadata">
  9.                     <a class="mr-2" href="#">{{ post.author }}</a>
  10.                     <small class="text-muted">{{ post.date_posted }}</small>
  11.                 </div>
  12.                 <h2><a class="article-title" href="{% url 'post_detail' post.date_posted.year post.date_posted.month post.date_posted.day post.slug %}">{{ post.title }}</a></h2>
  13.                 <p class="article-content">{{ post.content|slice:":200" }}...</p>
  14.             </div>
  15.         </article>
  16.     {% endfor %}
  17. {% endblock content %}
复制代码
post_detail.html

  1. <!-- blog/templates/blog/post_detail.html -->
  2. {% extends "base_generic.html" %}
  3. {% block content %}
  4.     <article class="media content-section">
  5.         <div class="media-body">
  6.             <div class="article-metadata">
  7.                 <a class="mr-2" href="#">{{ post.author }}</a>
  8.                 <small class="text-muted">{{ post.date_posted }}</small>
  9.             </div>
  10.             <h2 class="article-title">{{ post.title }}</h2>
  11.             <p class="article-content">{{ post.content }}</p>
  12.             <p>
  13.                 <a href="{% url 'post_list' %}">Back to list</a>
  14.             </p>
  15.             <h3>Comments</h3>
  16.             {% for comment in comments %}
  17.                 <div class="comment">
  18.                     <p class="info">
  19.                         {{ comment.name }} said on {{ comment.created }}
  20.                     </p>
  21.                     <p>{{ comment.body|linebreaks }}</p>
  22.                 </div>
  23.             {% endfor %}
  24.             {% if new_comment %}
  25.                 <h2>Your comment has been added.</h2>
  26.             {% else %}
  27.                 <h2>Add a new comment</h2>
  28.                 <form method="post">
  29.                     {{ comment_form.as_p }}
  30.                     {% csrf_token %}
  31.                     <input type="submit" value="Add comment">
  32.                 </form>
  33.             {% endif %}
  34.         </div>
  35.     </article>
  36. {% endblock content %}
复制代码
11. 创建底子模板

在 blog 应用目次下创建 templates 文件夹,并创建 base_generic.html 底子模板文件:
  1. <!-- blog/templates/base_generic.html -->
  2. <!DOCTYPE html>
  3. <html lang="en">
  4. <head>
  5.     <meta charset="UTF-8">
  6.     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7.     <title>{% block title %}My Blog{% endblock %}</title>
  8. </head>
  9. <body>
  10.     <header>
  11.         <h1><a href="{% url 'post_list' %}">My Blog</a></h1>
  12.     </header>
  13.     <main>
  14.         {% block content %}
  15.         {% endblock %}
  16.     </main>
  17.     <footer>
  18.         <p>&copy; 2023 My Blog</p>
  19.     </footer>
  20. </body>
  21. </html>
复制代码
12. 运行开发服务器

启动 Django 开发服务器,查看应用:
  1. python manage.py runserver
复制代码
访问 http://127.0.0.1:8000/blog/ 查看博客首页。
13. 添加用户认证

在 myblog 项目中,使用 Django 的内置用户认证体系。起首,创建一个用户模型(假如须要自定义用户模型):
  1. # myblog/models.py
  2. from django.contrib.auth.models import AbstractUser
  3. class CustomUser(AbstractUser):
  4.     # 添加自定义字段
  5.     pass
复制代码
在 settings.py 中指定自定义用户模型:
  1. AUTH_USER_MODEL = 'myblog.CustomUser'
复制代码
创建用户表:
  1. python manage.py makemigrations
  2. python manage.py migrate
复制代码
创建管理员用户:
  1. python manage.py createsuperuser
复制代码
登录 Django 管理后台:
  1. python manage.py runserver
复制代码
访问 http://127.0.0.1:8000/admin/,使用管理员用户登录。
14. 添加评论功能

在 blog/views.py 中,已经创建了评论表单和处理逻辑。确保在 post_detail 视图中处理评论提交。
15. 添加文章分类和标签功能

在 blog/views.py 中,添加分类和标签的过滤功能:
  1. from django.shortcuts import render, get_object_or_404
  2. from .models import Post, Comment, Category, Tag
  3. from .forms import CommentForm
  4. def post_list(request, category=None, tag=None):
  5.     posts = Post.objects.all().order_by('-date_posted')
  6.     if category:
  7.         posts = posts.filter(category__name=category)
  8.     if tag:
  9.         posts = posts.filter(tags__name=tag)
  10.     return render(request, 'blog/post_list.html', {'posts': posts})
  11. def post_detail(request, year, month, day, post):
  12.     post = get_object_or_404(Post, slug=post, date_posted__year=year, date_posted__month=month, date_posted__day=day)
  13.     comments = post.comments.filter(active=True)
  14.     new_comment = None
  15.     if request.method == 'POST':
  16.         comment_form = CommentForm(data=request.POST)
  17.         if comment_form.is_valid():
  18.             new_comment = comment_form.save(commit=False)
  19.             new_comment.post = post
  20.             new_comment.save()
  21.     else:
  22.         comment_form = CommentForm()
  23.     return render(request, 'blog/post_detail.html', {'post': post, 'comments': comments, 'new_comment': new_comment, 'comment_form': comment_form})
复制代码
在 blog/urls.py 中,添加分类和标签的 URL 模式:
  1. # blog/urls.py
  2. from django.urls import path
  3. from . import views
  4. urlpatterns = [
  5.     path('', views.post_list, name='post_list'),
  6.     path('category/<str:category>/', views.post_list, name='post_list_by_category'),
  7.     path('tag/<str:tag>/', views.post_list, name='post_list_by_tag'),
  8.     path('<int:year>/<int:month>/<int:day>/<slug:post>/', views.post_detail, name='post_detail'),
  9. ]
复制代码
16. 添加搜刮功能

在 blog/forms.py 中,创建搜刮表单:
  1. # blog/forms.py
  2. from django import forms
  3. class SearchForm(forms.Form):
  4.     query = forms.CharField()
复制代码
在 blog/views.py 中,添加搜刮功能:
  1. from django.shortcuts import render, get_object_or_404
  2. from .models import Post, Comment, Category, Tag
  3. from .forms import CommentForm, SearchForm
  4. from django.db.models import Q
  5. def post_list(request, category=None, tag=None):
  6.     posts = Post.objects.all().order_by('-date_posted')
  7.     if category:
  8.         posts = posts.filter(category__name=category)
  9.     if tag:
  10.         posts = posts.filter(tags__name=tag)
  11.     if 'query' in request.GET:
  12.         query = request.GET['query']
  13.         posts = posts.filter(Q(title__icontains=query) | Q(content__icontains=query))
  14.     return render(request, 'blog/post_list.html', {'posts': posts})
  15. def post_detail(request, year, month, day, post):
  16.     post = get_object_or_404(Post, slug=post, date_posted__year=year, date_posted__month=month, date_posted__day=day)
  17.     comments = post.comments.filter(active=True)
  18.     new_comment = None
  19.     if request.method == 'POST':
  20.         comment_form = CommentForm(data=request.POST)
  21.         if comment_form.is_valid():
  22.             new_comment = comment_form.save(commit=False)
  23.             new_comment.post = post
  24.             new_comment.save()
  25.     else:
  26.         comment_form = CommentForm()
  27.     return render(request, 'blog/post_detail.html', {'post': post, 'comments': comments, 'new_comment': new_comment, 'comment_form': comment_form})
复制代码
在 blog/templates/blog/post_list.html 中,添加搜刮表单:
  1. <!-- blog/templates/blog/post_list.html -->
  2. {% extends "base_generic.html" %}
  3. {% block content %}
  4.     <h2>Blog Home</h2>
  5.     <form method="get">
  6.         {{ search_form.as_p }}
  7.     </form>
  8.     {% for post in posts %}
  9.         <article class="media content-section">
  10.             <div class="media-body">
  11.                 <div class="article-metadata">
  12.                     <a class="mr-2" href="#">{{ post.author }}</a>
  13.                     <small class="text-muted">{{ post.date_posted }}</small>
  14.                 </div>
  15.                 <h2><a class="article-title" href="{% url 'post_detail' post.date_posted.year post.date_posted.month post.date_posted.day post.slug %}">{{ post.title }}</a></h2>
  16.                 <p class="article-content">{{ post.content|slice:":200" }}...</p>
  17.             </div>
  18.         </article>
  19.     {% endfor %}
  20. {% endblock content %}
复制代码
17. 添加分页功能

在 blog/views.py 中,添加分页功能:
  1. from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
  2. def post_list(request, category=None, tag=None):
  3.     posts = Post.objects.all().order_by('-date_posted')
  4.     if category:
  5.         posts = posts.filter(category__name=category)
  6.     if tag:
  7.         posts = posts.filter(tags__name=tag)
  8.     if 'query' in request.GET:
  9.         query = request.GET['query']
  10.         posts = posts.filter(Q(title__icontains=query) | Q(content__icontains=query))
  11.     paginator = Paginator(posts, 10)  # 每页显示 10 条
  12.     page = request.GET.get('page')
  13.     try:
  14.         posts = paginator.page(page)
  15.     except PageNotAnInteger:
  16.         posts = paginator.page(1)
  17.     except EmptyPage:
  18.         posts = paginator.page(paginator.num_pages)
  19.     return render(request, 'blog/post_list.html', {'posts': posts})
复制代码
在 blog/templates/blog/post_list.html 中,添加分页导航:
  1. <!-- blog/templates/blog/post_list.html -->
  2. {% extends "base_generic.html" %}
  3. {% block content %}
  4.     <h2>Blog Home</h2>
  5.     <form method="get">
  6.         {{ search_form.as_p }}
  7.     </form>
  8.     {% for post in posts %}
  9.         <article class="media content-section">
  10.             <div class="media-body">
  11.                 <div class="article-metadata">
  12.                     <a class="mr-2" href="#">{{ post.author }}</a>
  13.                     <small class="text-muted">{{ post.date_posted }}</small>
  14.                 </div>
  15.                 <h2><a class="article-title" href="{% url 'post_detail' post.date_posted.year post.date_posted.month post.date_posted.day post.slug %}">{{ post.title }}</a></h2>
  16.                 <p class="article-content">{{ post.content|slice:":200" }}...</p>
  17.             </div>
  18.         </article>
  19.     {% endfor %}
  20.     <div class="pagination">
  21.         <span class="step-links">
  22.             {% if posts.has_previous %}
  23.                 <a href="?page=1">&laquo; first</a>
  24.                 <a href="?page={{ posts.previous_page_number }}">previous</a>
  25.             {% endif %}
  26.             <span class="current">
  27.                 Page {{ posts.number }} of {{ posts.paginator.num_pages }}.
  28.             </span>
  29.             {% if posts.has_next %}
  30.                 <a href="?page={{ posts.next_page_number }}">next</a>
  31.                 <a href="?page={{ posts.paginator.num_pages }}">last &raquo;</a>
  32.             {% endif %}
  33.         </span>
  34.     </div>
  35. {% endblock content %}
复制代码
18. 添加静态文件和媒体文件管理

在 settings.py 中设置静态文件和媒体文件:
  1. # settings.py
  2. STATIC_URL = '/static/'
  3. STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
  4. MEDIA_URL = '/media/'
  5. MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
复制代码
在 urls.py 中添加静态文件和媒体文件的 URL 设置:
  1. # myblog/urls.py
  2. from django.contrib import admin
  3. from django.urls import include, path
  4. from django.conf import settings
  5. from django.conf.urls.static import static
  6. urlpatterns = [
  7.     path('admin/', admin.site.urls),
  8.     path('blog/', include('blog.urls')),
  9. ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
复制代码
19. 添加用户注册和登录功能

在 blog 应用中,创建用户注册和登录表单:
  1. # blog/forms.py
  2. from django import forms
  3. from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
  4. from django.contrib.auth.models import User
  5. class SignUpForm(UserCreationForm):
  6.     email = forms.EmailField(max_length=254, help_text='Required. Inform a valid email address.')
  7.     class Meta:
  8.         model = User
  9.         fields = ('username', 'email', 'password1', 'password2')
  10. class LoginForm(AuthenticationForm):
  11.     username = forms.CharField(label='Username', max_length=254)
  12.     password = forms.CharField(label='Password', widget=forms.PasswordInput)
复制代码
在 blog/views.py 中,添加用户注册和登录视图:
  1. from django.shortcuts import render, redirect
  2. from django.contrib.auth import login, authenticate
  3. from .forms import SignUpForm, LoginForm
  4. def signup(request):
  5.     if request.method == 'POST':
  6.         form = SignUpForm(request.POST)
  7.         if form.is_valid():
  8.             user = form.save()
  9.             user.refresh_from_db()  # load the profile instance created by the signal
  10.             user.save()
  11.             raw_password = form.cleaned_data.get('password1')
  12.             user = authenticate(username=user.username, password=raw_password)
  13.             login(request, user)
  14.             return redirect('post_list')
  15.     else:
  16.         form = SignUpForm()
  17.     return render(request, 'blog/signup.html', {'form': form})
  18. def user_login(request):
  19.     if request.method == 'POST':
  20.         form = LoginForm(data=request.POST)
  21.         if form.is_valid():
  22.             user = form.get_user()
  23.             login(request, user)
  24.             return redirect('post_list')
  25.     else:
  26.         form = LoginForm()
  27.     return render(request, 'blog/login.html', {'form': form})
复制代码
在 blog/urls.py 中,添加用户注册和登录的 URL 模式:
  1. # blog/urls.py
  2. from django.urls import path
  3. from . import views
  4. urlpatterns = [
  5.     path('', views.post_list, name='post_list'),
  6.     path('category/<str:category>/', views.post_list, name='post_list_by_category'),
  7.     path('tag/<str:tag>/', views.post_list, name='post_list_by_tag'),
  8.     path('<int:year>/<int:month>/<int:day>/<slug:post>/', views.post_detail, name='post_detail'),
  9.     path('signup/', views.signup, name='signup'),
  10.     path('login/', views.user_login, name='login'),
  11. ]
复制代码
在 blog/templates/blog/signup.html 和 blog/templates/blog/login.html 中,创建用户注册和登录模板:
  1. <!-- blog/templates/blog/signup.html -->
  2. {% extends "base_generic.html" %}
  3. {% block content %}
  4.     <h2>Sign up</h2>
  5.     <form method="post">
  6.         {% csrf_token %}
  7.         {{ form.as_p }}
  8.         <button type="submit">Sign up</button>
  9.     </form>
  10. {% endblock %}
复制代码
  1. <!-- blog/templates/blog/login.html -->
  2. {% extends "base_generic.html" %}
  3. {% block content %}
  4.     <h2>Login</h2>
  5.     <form method="post">
  6.         {% csrf_token %}
  7.         {{ form.as_p }}
  8.         <button type="submit">Login</button>
  9.     </form>
  10. {% endblock %}
复制代码
20. 添加用户注销功能

在 blog/views.py 中,添加用户注销视图:
  1. from django.contrib.auth import logout
  2. from django.shortcuts import redirect
  3. def user_logout(request):
  4.     logout(request)
  5.     return redirect('post_list')
复制代码
在 blog/urls.py 中,添加用户注销的 URL 模式:
  1. # blog/urls.py
  2. from django.urls import path
  3. from . import views
  4. urlpatterns = [
  5.     path('', views.post_list, name='post_list'),
  6.     path('category/<str:category>/', views.post_list, name='post_list_by_category'),
  7.     path('tag/<str:tag>/', views.post_list, name='post_list_by_tag'),
  8.     path('<int:year>/<int:month>/<int:day>/<slug:post>/', views.post_detail, name='post_detail'),
  9.     path('signup/', views.signup, name='signup'),
  10.     path('login/', views.user_login, name='login'),
  11.     path('logout/', views.user_logout, name='logout'),
  12. ]
复制代码
21. 添加用户个人资料页面

在 blog/models.py 中,添加用户个人资料模型:
  1. # blog/models.py
  2. from django.contrib.auth.models import User
  3. from django.db import models
  4. class Profile(models.Model):
  5.     user = models.OneToOneField(User, on_delete=models.CASCADE)
  6.     bio = models.TextField(max_length=500, blank=True)
  7.     location = models.CharField(max_length=100, blank=True)
  8.     birth_date = models.DateField(null=True, blank=True)
  9.     def __str__(self):
  10.         return f'{self.user.username} Profile'
复制代码
在 blog/forms.py 中,添加用户个人资料表单:
  1. # blog/forms.py
  2. from django import forms
  3. from .models import Profile
  4. class ProfileForm(forms.ModelForm):
  5.     class Meta:
  6.         model = Profile
  7.         fields = ('bio', 'location', 'birth_date')
复制代码
在 blog/views.py 中,添加用户个人资料视图:
  1. from django.shortcuts import render, redirect
  2. from django.contrib.auth.decorators import login_required
  3. from .forms import ProfileForm
  4. @login_required
  5. def profile(request):
  6.     if request.method == 'POST':
  7.         form = ProfileForm(request.POST, instance=request.user.profile)
  8.         if form.is_valid():
  9.             form.save()
  10.             return redirect('profile')
  11.     else:
  12.         form = ProfileForm(instance=request.user.profile)
  13.     return render(request, 'blog/profile.html', {'form': form})
复制代码
在 blog/urls.py 中,添加用户个人资料的 URL 模式:
  1. # blog/urls.py
  2. from django.urls import path
  3. from . import views
  4. urlpatterns = [
  5.     path('', views.post_list, name='post_list'),
  6.     path('category/<str:category>/', views.post_list, name='post_list_by_category'),
  7.     path('tag/<str:tag>/', views.post_list, name='post_list_by_tag'),
  8.     path('<int:year>/<int:month>/<int:day>/<slug:post>/', views.post_detail, name='post_detail'),
  9.     path('signup/', views.signup, name='signup'),
  10.     path('login/', views.user_login, name='login'),
  11.     path('logout/', views.user_logout, name='logout'),
  12.     path('profile/', views.profile, name='profile'),
  13. ]
复制代码
在 blog/templates/blog/profile.html 中,创建用户个人资料模板:
  1. <!-- blog/templates/blog/profile.html -->
  2. {% extends "base_generic.html" %}
  3. {% block content %}
  4.     <h2>Profile</h2>
  5.     <form method="post">
  6.         {% csrf_token %}
  7.         {{ form.as_p }}
  8.         <button type="submit">Save</button>
  9.     </form>
  10. {% endblock %}
复制代码
22. 添加定时任务

使用 django-celery-beat 添加定时任务,例如定期清算旧评论:

  • 安装 Celery 和 django-celery-beat:
    1. pip install celery django-celery-beat
    复制代码
  • 在 settings.py 中设置 Celery:
    1. # settings.py
    2. CELERY_BROKER_URL = 'redis://localhost:6379/0'
    3. CELERY_RESULT_BACKEND = 'redis://localhost:6379/0'
    复制代码
  • 创建 celery.py 文件设置 Celery:
    1. # myblog/celery.py
    2. from __future__ import absolute_import, unicode_literals
    3. import os
    4. from celery import Celery
    5. os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myblog.settings')
    6. app = Celery('myblog')
    7. app.config_from_object('django.conf:settings', namespace='CELERY')
    8. app.autodiscover_tasks()
    复制代码
  • 在 __init__.py 中导入 Celery 应用:
    1. # myblog/__init__.py
    2. from __future__ import absolute_import, unicode_literals
    3. # This will make sure the app is always imported when
    4. # Django starts so that shared_task will use this app.
    5. from .celery import app as celery_app
    6. __all__ = ('celery_app',)
    复制代码
  • 创建定时任务函数:
    1. # blog/tasks.py
    2. from celery import shared_task
    3. from django.utils import timezone
    4. from .models import Comment
    5. @shared_task
    6. def cleanup_old_comments():
    7.     one_week_ago = timezone.now() - timezone.timedelta(days=7)
    8.     Comment.objects.filter(created__lt=one_week_ago).delete()
    复制代码
  • 在 settings.py 中设置定时任务:
    1. from celery.schedules import crontab
    2. CELERY_BEAT_SCHEDULE = {
    3.     'cleanup-old-comments': {
    4.         'task': 'blog.tasks.cleanup_old_comments',
    5.         'schedule': crontab(minute=0, hour=0),  # 每天午夜执行
    6.     },
    7. }
    复制代码
  • 启动 Celery Worker 和 Celery Beat:
    1. celery -A myblog worker -l info
    2. celery -A myblog beat -l info
    复制代码
23. 添加邮件通知功能

使用 Django 的邮件功能,发送邮件通知,例如在用户评论时通知博主:

  • 在 settings.py 中设置邮件发送:
    1. # settings.py
    2. EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
    3. EMAIL_HOST = 'smtp.gmail.com'
    4. EMAIL_PORT = 587
    5. EMAIL_USE_TLS = True
    6. EMAIL_HOST_USER = 'your-email@gmail.com'
    7. EMAIL_HOST_PASSWORD = 'your-email-password'
    复制代码
  • 在 blog/views.py 中,添加邮件通知功能:
    1. from django.core.mail import send_mail
    2. from django.conf import settings
    3. def post_detail(request, year, month, day, post):
    4.     post = get_object_or_404(Post, slug=post, date_posted__year=year, date_posted__month=month, date_posted__day=day)
    5.     comments = post.comments.filter(active=True)
    6.     new_comment = None
    7.     if request.method == 'POST':
    8.         comment_form = CommentForm(data=request.POST)
    9.         if comment_form.is_valid():
    10.             new_comment = comment_form.save(commit=False)
    11.             new_comment.post = post
    12.             new_comment.save()
    13.             send_mail(
    14.                 f'New comment on {post.title}',
    15.                 f'New comment added by {new_comment.name} on {post.title}',
    16.                 settings.EMAIL_HOST_USER,
    17.                 [post.author.email],
    18.                 fail_silently=False,
    19.             )
    20.     else:
    21.         comment_form = CommentForm()
    22.     return render(request, 'blog/post_detail.html', {'post': post, 'comments': comments, 'new_comment': new_comment, 'comment_form': comment_form})
    复制代码
24. 添加静态文件和媒体文件管理

在 settings.py 中设置静态文件和媒体文件:
  1. # settings.py
  2. STATIC_URL = '/static/'
  3. STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
  4. MEDIA_URL = '/media/'
  5. MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
复制代码
在 urls.py 中添加静态文件和媒体文件的 URL 设置:
  1. # myblog/urls.py
  2. from django.contrib import admin
  3. from django.urls import include, path
  4. from django.conf import settings
  5. from django.conf.urls.static import static
  6. urlpatterns = [
  7.     path('admin/', admin.site.urls),
  8.     path('blog/', include('blog.urls')),
  9. ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
复制代码
25. 摆设应用

摆设 Django 应用到生产情况,可以使用多种方式,如 Heroku、AWS、DigitalOcean 等。以下是一个简朴的 Heroku 摆设指南:

  • 安装 Heroku CLI:
    1. curl https://cli-assets.heroku.com/install.sh | sh
    复制代码
  • 登录 Heroku:
    1. heroku login
    复制代码
  • 创建 Heroku 应用:
    1. heroku create myblogapp
    复制代码
  • 设置 Heroku 情况变量:
    1. heroku config:set DJANGO_SETTINGS_MODULE=myblog.settings
    2. heroku config:set SECRET_KEY=your-secret-key
    3. heroku config:set DEBUG=False
    复制代码
  • 摆设应用:
    1. git init
    2. git add .
    3. git commit -m "Initial commit"
    4. git push heroku master
    复制代码
  • 迁移数据库:
    1. heroku run python manage.py migrate
    复制代码
  • 创建管理员用户:
    1. heroku run python manage.py createsuperuser
    复制代码
通过以上步骤,你可以创建一个功能全面的 Django 博客应用项目,包括用户认证、评论功能、文章分类和标签、搜刮功能、分页功能、定时任务、邮件通知、静态文件和媒体文件管理等。渴望这个指南对你有所帮助!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

篮之新喜

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表