Django搭建个人博客Blog-Day05

news/2024/11/20 11:31:53/

创建文章模块

创建文章app
  1. 在虚拟环境中,apps路径下使用如下代码:

# 进入虚拟环境
workon wsl
# 进入要创建app的路径下
cd blog/blog/apps
# 创建app
python ../../manage.py startapp articles
  1. 将articles注册进配置文件dev.py中的INSTALLED_APPS

INSTALLED_APPS = [...'articles',
]
  1. 创建数据模型,在blog/blog/apps/articles/models.py文件中添加如下代码

from django.db import modelsfrom user.models import BaseModel
from user.models import User# 创建数据模型
# 博客文章数据模型    应该有哪些字段?
# 
class Articles(BaseModel):  # BaseModel  # 文章正文内容   TextFieldbody = models.TextField(verbose_name='正文')# 文章标题      CharFieldtitle = models.CharField(max_length=100,verbose_name='标题')# 文章封面图片  ImageFieldavatar = models.ImageField(upload_to='articles/%Y%m%d/',verbose_name='文章封面')# 文章摘要      CharFielddesc  =models.CharField(max_length=255,verbose_name='文章摘要')# 文章的浏览量   IntegerFieldread_num = models.IntegerField(verbose_name='文章浏览量',default=0)# 文章的作者    外键   文章是多的   用户是一的    外键字段写在哪一方? 多的这一方author = models.ForeignKey(User,on_delete=models.CASCADE)# 文章的专栏    CharField    外键字段    专栏表  一对多  多  column = models.ForeignKey('Column',on_delete=models.CASCADE)class Meta:db_table = 'blog_articles'verbose_name = '文章'verbose_name_plural = verbose_nameclass Column(BaseModel):# 专栏的名字title = models.CharField(max_length=100, verbose_name='专栏标题')class Meta:db_table = 'blog_column'verbose_name = '专栏'verbose_name_plural = verbose_namedef __str__(self):# 打印一个对象的时候return self.title
  1. 执行数据库迁移,生成对应的数据表(在虚拟环境中,manage.py文件下)

python manage.py makemigrations
python manage.py migrate
将文章模块中的数据模型加入后台管理
  1. 在admin.py文件中添加如下代码:

from django.contrib import admin
from articles.models import Articles,Column# Register your models here.
class ArticlesAdmin(admin.ModelAdmin):list_display = ['title','author','create_time']# 想通过作者来搜索 ==》 通过作者的名字来搜索  ===》search_fields = ['title','author__username']class ColumnAdmin(admin.ModelAdmin):list_display = ['title','create_time']# 想通过作者来搜索 ==》 通过作者的名字来搜索  ===》search_fields = ['title']# 将原来的数据模型和ModelAdmin结合起来
admin.site.register(Articles,ArticlesAdmin)
admin.site.register(Column,ColumnAdmin)
  1. 在apps.py文件中添加如下代码:

from django.apps import AppConfigclass ArticlesConfig(AppConfig):name = 'articles'verbose_name = '文章管理'
  1. 在__init__.py文件中添加如下代码:

default_app_config = 'articles.apps.ArticlesConfig'

实现创建文章

  1. 写路由(总路由)

from django.contrib import admin
from django.urls import path,include
from django.conf.urls.static import static
from django.conf import settingsurlpatterns = [path('admin/', admin.site.urls),# 进行路由分发path('user/',include('user.urls')),path('password-reset',include('password_reset.urls')),path('',include('articles.urls')),
]+static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
  1. 在articles文件夹下创建urls.py文件,添加如下代码,用作路由分发:

from django.urls import pathfrom . import viewsapp_name = 'articles'urlpatterns = [# 创建文章path('create',views.Create.as_view(),name='create'),path('index',views.index,name='index'),
]
  1. 写视图(view.py)

from django.http import HttpResponse
from django.shortcuts import render,redirect,reversefrom user.views import LoginRequired
from articles.models import Column,Articles# 继承LoginRequired   只有用户登录了以后才能访问
class Create(LoginRequired):# 展示创建文章的html页面def get(self,requests):# 先查出来所有的专栏,展示在html页面中,让用户去勾选columns = Column.objects.all()return render(requests,'articles/create.html',locals())# 实现创建文章的功能逻辑def post(self,requests):# 接受请求数据title = requests.POST.get('title')desc = requests.POST.get('desc')body = requests.POST.get('body')column = requests.POST.get('column')# 用户  就是当前登录的用户author = requests.user# 封面图  文件是通过FILES接受的avatar = requests.FILES.get('avatar')# 数据入库try:Articles.objects.create(author=author,title=title,body=body,desc=desc,avatar=avatar,column_id=column)# 返回结果return redirect(reverse('articles:index'))except Exception as err:return render(requests,'articles/create.html',{'errmsg':'请选择专栏'})def index(request):return HttpResponse('首页')
  1. 在templates/目录下创建articles/create.html,并添加如下代码:

{% extends 'base.html' %}
{% block title %}创建文章{% endblock title %}
{% block content %}<div class="container"><div class="row"><div class="clo-12"><form action="" method="post" enctype="multipart/form-data">{% csrf_token %}<!--文章标题 --><div class="form-group"><label for="title">文章标签</label><input type="text" class="form-control" id="title" name="title"></div><!--文章专栏 --><div class="form-group"><label for="column">文章专栏</label><select name="column" id="column" class="form-control"><option value="none">请选择专栏</option>{% for column in columns %}<option value="{{ column.id }}">{{ column.title }}</option>{% endfor %}</select></div><!--文章摘要 --><div class="form-group"><label for="desc">文章摘要</label><input type="text" class="form-control" id="desc" name="desc"></div><!--文章图片 --><div class="form-group"><label for="avatar">文章封面</label><input type="file" class="form-control" id="avatar" name="avatar"></div><!--文章正文 --><div class="form-group"><label for="body">文章正文</label><textarea class="form-control" name="body" id="body" cols="30" rows="10"></textarea></div><!--提交按钮 --><button type="submit" class="btn btn-success">完成</button></form></div></div></div>
<!--展示错误信息 -->{% if errmsg %}<div class="alert alert-danger alert-dismissible"><strong>错误!</strong>{{ errmsg }}</div>{% endif %}
{% endblock content %}

实现修改文章

  1. 写视图(view.py)

class Update(LoginRequired):# 展示创建文章的html页面def get(self,requests,id):# 先查出来要修改的文章   展示在html中article = get_object_or_404(Articles,pk=id)# 先查出来所有的专栏,展示在html页面中,让用户去勾选columns = Column.objects.all()return render(requests,'articles/update.html',locals())# 实现创建文章的功能逻辑def post(self,requests,id):# 对指定的文章进行修改# 1. 先查出文章article = get_object_or_404(Articles, pk=id)# 2. 判断文章的作者是不是登录的用户,是则能修改,不是就不能修改if requests.user == article.author:# 接受数据article.title = requests.POST.get('title')article.desc = requests.POST.get('desc')article.body = requests.POST.get('body')column = requests.POST.get('column')avatar = requests.FILES.get('avatar')if avatar:article.avatar = avatar# 专栏是外键字段article.column  =get_object_or_404(Column,pk=column)# 数据入库article.save()# 返回结果return redirect(reverse('articles:index'))return HttpResponse('不能修改其他作者的文章')
  1. 写路由(articles/urls.py)

from django.urls import path
from . import viewsapp_name = 'articles'
urlpatterns = [# 创建文章path('create',views.Create.as_view(),name='create'),path('update/<int:id>',views.Update.as_view(),name='update'),path('index',views.index,name='index'),
]
  1. 在templates/articles/文件夹下创建update.html文件,添加如下代码:

{% extends "base.html" %}
{% block title %} 更新文章 {% endblock title %}
{% block content %}
<div class="container"><div class="row"><div class="col-12"><br><form method="post" action="" enctype="multipart/form-data">{% csrf_token %}<div class="form-group"><label for="title">文章标题</label><!-- 在 value 属性中指定文本框的初始值为旧的内容,即 article 对象中的 title 字段 --><input type="text" class="form-control" id="title" name="title" value="{{ article.title }}"></div><!-- 文章栏目 --><div class="form-group"><label for="column">栏目</label><select class="form-control"  id="column" name="column"><option value="none">请选择栏目..</option>{% for column in columns %}<option value="{{ column.id }}"{% if column.id == article.column.id %}selected{% endif %}>{{ column }}</option>{% endfor %}</select></div><div class="form-group"><!-- avatar --><label for="avatar">文章图片</label><!-- 有封面则展示封面 -->{% if article.avatar %}<img src="{{ article.avatar.url }}" style="max-width: 20%; border-radius: 15%;" class="col-md-4"><input type="file" class="form-control-file" name="avatar" id="avatar">{% else %}<h5 class="col-md-4">请上传文章图片</h5><input type="file" class="form-control-file" name="avatar" id="avatar">{% endif %}<!-- 有头像则展示头像 --></div><!-- 文章摘要 --><div class="form-group"><!-- 标签 --><label for="desc">文章摘要</label><!-- 文本框 --><input type="text" class="form-control" id="desc" name="desc" value="{{ article.desc }}"></div><div class="form-group"><label for="body">文章正文</label><!-- 文本域不需要 value 属性,直接在标签体中嵌入数据即可 --><textarea type="text" class="form-control" id="body" name="body" rows="12">{{ article.body }}</textarea></div><button type="submit" class="btn btn-primary">完成</button></form></div></div>
</div>
{% endblock content %}

实现删除文章

  1. 写视图(view.py)

def delete(requests,id):# 1. 先根据ID查出文章article = get_object_or_404(Articles, pk=id)# 2. 判断当前登录用户是不是作者if requests.user == article.author:# 3. 如果是作者就删除文章 数据入库article.delete()return redirect(reverse('articles:index'))# 4. 如果不是作者,就提示不能删return HttpResponse('不能删除其他作者的文章')
  1. 写路由(urls.py)

from django.urls import path
from . import viewsapp_name = 'articles'
urlpatterns = [# 创建文章path('create',views.Create.as_view(),name='create'),path('update/<int:id>',views.Update.as_view(),name='update'),path('delete/<int:id>',views.delete,name='delete'),path('index',views.index,name='index'),
]

展示所有文章

基础版本(无分页)

  1. 写视图(view.py)

def index(request):# 获取所有的文章,再展示在html页面中articles = Articles.objects.all()return render(request,'articles/index.html',locals())
  1. 写路由(总路由)

from django.urls import path,include
from django.conf.urls.static import static
from django.conf import settingsfrom articles.views import indexurlpatterns = [path('',index,name='index'),path('admin/', admin.site.urls),# 进行路由分发path('user/',include('user.urls')),path('password-reset',include('password_reset.urls')),path('',include('articles.urls')),
]+static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
  1. 写路由(articles/urls.py)

from django.urls import path
from . import viewsapp_name = 'articles'
urlpatterns = [# 创建文章path('create',views.Create.as_view(),name='create'),path('update/<int:id>',views.Update.as_view(),name='update'),path('delete/<int:id>',views.delete,name='delete'),# 展示所有的博文path('index',views.index,name='index'),
]
  1. 在templates/articles/文件夹下创建index.html文件并添加如下代码:

{% extends "base.html" %}
{% block title %} 博客正文 {% endblock title %}
{% block content %}<div class="container"><div class="col-12"><div class="row mt-2">{% for article in articles %}<!-- 封面图-->{% if article.avatar %}<div class="col-3"><img src="{{ article.avatar.url }}" alt="avatar" style="max-width: 100%;border-radius:20px "></div>{% endif %}<!-- 文章内容--><div class="col"><!-- 文章栏目--><button type="button" class="btn btn-sm mb-2 btn-success">{{ article.column }}</button><!-- 文章标题--><h4><b><a href="{% url 'articles:detail' article.id %}">{{ article.title }}</a></b></h4><!-- 文章摘要--><div><p style="color: gray;">{% if article.desc %}{{ article.desc }}{% else %}还没有摘要{% endif %}</p></div><!-- 其他信息--><p><span style="color: green">作者:{{ article.author }}&nbsp;&nbsp;&nbsp;</span><span style="color: green">浏览量:{{ article.read_num }}&nbsp;&nbsp;&nbsp;</span><span style="color: green">发布时间:{{ article.create_time|date:'Y-m-d' }}&nbsp;&nbsp;&nbsp;</span><span style="color: green">更新时间:{{ article.update_time|date:'Y-m-d' }}&nbsp;&nbsp;&nbsp;</span></p></div><hr style="width: 100%;">{% endfor %}</div></div></div>
{% endblock content %}

展示文章详情页

  1. 写视图(view.py)

# 查看文章详情
def detail(request,id):# 根据文章的ID 查出对应的文章展示在html页面中article = get_object_or_404(Articles, pk=id)# 没查看一次文章 就增加一次浏览量article.read_num += 1article.save()return render(request,'articles/detail.html',locals())
  1. 写视图(urls.py)

from django.urls import path
from . import viewsapp_name = 'articles'
urlpatterns = [# 创建文章path('create',views.Create.as_view(),name='create'),path('update/<int:id>',views.Update.as_view(),name='update'),path('delete/<int:id>',views.delete,name='delete'),# 展示所有的博文path('index',views.index,name='index'),# 查看博文详情path('detail/<int:id>',views.detail,name='detail'),
]
  1. 在templates/articles/文件夹下创建detail.html文件:

{% extends 'base.html' %}
{% block title %}文章详情{% endblock title %}
{% block content %}<div class="container"><div class="row"><div class="col-9"><!--标题和作者--><h1 class="mt-4 mb-4">{{ article.title }}</h1><div class="alert alert-success">作者:{{ article.author }}创建时间:{{ article.create_time|date:'Y-m-d' }}文章浏览量:{{ article.read_num }}<!--如果当前登录的用户就是作者,则展示删除文章和修改文章-->{% if request.user == article.author %}<a href="#" onclick="confirm_delete()">删除文章</a><a href="{% url 'articles:update' article.id %}">修改文章</a>{% endif %}<!--文章的专栏--><button type="button" class="btn btn-success btn-sm mb-2">{{ article.column }}</button></div><!--文章的正文--><div class="col-12"><p>{{ article.body }}</p></div></div></div></div><script>//删除文章的函数function confirm_delete(){// 调用layer弹窗组件layer.open({title:"确认删除",content:'确认删除这篇文章吗?',yes:function (index,layero){// 指定前往的urllocation.href = '{% url "articles:delete" article.id %}'},})}</script>
{% endblock content %}

http://www.ppmy.cn/news/12536.html

相关文章

make_blobs函数

示例1&#xff1a; # make_blobs示例 from sklearn.datasets.samples_generator import make_blobsX, y make_blobs(n_samples10, centers3, n_features2,random_state0) #看看数据集长什么样 plt.scatter(X[:, 0], X[:, 1], cy, cmap"rainbow");示例2&#xff1a;…

Linux chattr命令

Linux chattr命令Linux 命令大全Linux chattr命令用于改变文件属性。这项指令可改变存放在ext2文件系统上的文件或目录属性&#xff0c;这些属性共有以下8种模式&#xff1a;a&#xff1a;让文件或目录仅供附加用途。b&#xff1a;不更新文件或目录的最后存取时间。c&#xff1…

监控需求以及开源方案的对比

文章目录监控需求以及开源方案的对比监控需求来源可观测性三大支柱指标监控日志链路追踪业界方案横评ZabbixZabbix优点Zabbix缺点Open-FalconOpen-Falcon 的优点Open-Falcon 的缺点PrometheusPrometheus 的优点Prometheus 的缺点NightingaleNightingale 的优点Nightingale 的缺…

FPGA:IIC验证镁光EEPROM仿真模型(纯Verilog)

目录日常唠嗑一、程序设计二、镁光模型仿真验证三、testbench文件四、完整工程下载日常唠嗑 IIC协议这里就不赘述了&#xff0c;网上很多&#xff0c;这里推荐两个&#xff0c;可以看看【接口时序】6、IIC总线的原理与Verilog实现 &#xff0c;还有IIC协议原理以及主机、从机Ve…

Linux文件目录与路径、内容查找命令及文件颜色知识总结

✅作者简介&#xff1a;热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏&#xff1a;Java案例分…

2023.1.16 (一) 上午 关于人口老龄化的研究——老龄化的式子表示及建国以来的老龄化情况

2023.1.16&#xff08;一&#xff09;上午 关于人口老龄化的研究——老龄化的式子表示及建国以来的老龄化情况前言定义建模模型细节代码实现.in文件.out文件前言 今天研究一个简单一点的问题&#xff0c;预计2023.1.18正式结题做PPT展示。 定义 老龄人: 60岁≤ 的人 老龄化&…

测开-基础篇

目录 一、软件测试的生命周期 &#x1f351;软件的生命周期 &#x1f351;软件测试的生命周期 二、如何描述一个BUG&#xff1f; 三、BUG的等级 四、BUG的生命周期 五、面试题&#xff1a;关于BUG&#xff0c;与开发人员产生纠纷怎么办&#xff1f; 一、软件测试的生命周…

whistle抓包工具应用

原文地址&#xff1a;(67条消息) whistle抓包工具学习_BBC蟹耳总的博客-CSDN博客_w2 抓包 一、安装whistle 首先安装好whistle抓包工具&#xff0c;有以下两个步骤 在终端中全局安装whistle&#xff1a;npm install -g whistle可以通过whistle help查看相关信息&#xff0c;…