Python从点滴开始——官网博客项目从0开始改造(二)

一、创建数据库模型

1、基本的原则如下:

	每个模型在Django中的存在形式为一个Python类
	每个模型都是django.db.models.Model的子类
	模型里的每个类代表数据库中的一个表
	模型的每个字段(属性)代表数据表的某一列
	Django将自动为你生成数据库访问API
	
	博客项目数据类型,我们需要存储六种数据:文章分类、文章、文章标签、幻灯图、推荐位、友情链接。每种数据一个表

2、博客模型代码

打开blog/models.py,输入代码:

from django.db import models
from django.contrib.auth.models import User


# 导入Django自带用户模块

# 文章分类
class Category(models.Model):
    name = models.CharField('博客分类', max_length=100)
    index = models.IntegerField(default=999, verbose_name='分类排序')

    class Meta:
        verbose_name = '博客分类'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name


# 文章标签
class Tag(models.Model):
    name = models.CharField('文章标签', max_length=100)

    class Meta:
        verbose_name = '文章标签'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name


# 推荐位
class Tui(models.Model):
    name = models.CharField('推荐位', max_length=100)

    class Meta:
        verbose_name = '推荐位'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name


# 文章
class Article(models.Model):
    title = models.CharField('标题', max_length=70)
    excerpt = models.TextField('摘要', max_length=200, blank=True)
    category = models.ForeignKey(Category, on_delete=models.DO_NOTHING, verbose_name='分类', blank=True, null=True)
    # 使用外键关联分类表与分类是一对多关系
    tags = models.ManyToManyField(Tag, verbose_name='标签', blank=True)
    # 使用外键关联标签表与标签是多对多关系
    img = models.ImageField(upload_to='article_img/%Y/%m/%d/', verbose_name='文章图片', blank=True, null=True)
    body = models.TextField()


    user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='作者')
    """
    文章作者,这里User是从django.contrib.auth.models导入的。
    这里我们通过 ForeignKey 把文章和 User 关联了起来。
    """
    views = models.PositiveIntegerField('阅读量', default=0)
    tui = models.ForeignKey(Tui, on_delete=models.DO_NOTHING, verbose_name='推荐位', blank=True, null=True)

    created_time = models.DateTimeField('发布时间', auto_now_add=True)
    modified_time = models.DateTimeField('修改时间', auto_now=True)


    class Meta:
        verbose_name = '文章'
        verbose_name_plural = '文章'


    def __str__(self):
        return self.title


# Banner
class Banner(models.Model):
    text_info = models.CharField('标题', max_length=50, default='')
    img = models.ImageField('轮播图', upload_to='banner/')
    link_url = models.URLField('图片链接', max_length=100)
    is_active = models.BooleanField('是否是active', default=False)

    def __str__(self):
        return self.text_info

    class Meta:
        verbose_name = '轮播图'
        verbose_name_plural = '轮播图'


# 友情链接
class Link(models.Model):
    name = models.CharField('链接名称', max_length=20)
    linkurl = models.URLField('网址', max_length=100)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = '友情链接'
        verbose_name_plural = '友情链接'

这里面我们多增加了一个img图片封面字段,用于上传文章封面图片的,article_img/为上传目录,%Y/%m/%d/为自动在上传的图片上加上文件上传的时间。

在迁移之前,我们先需要设置数据库,如果我们使用默认的数据库的话,就不需要设置,Django默认使用

sqlite3数据库,如果我们想使用Mysql数据库的话,则需要我们单独配置。我们打开settings.py文件,找到DATABASES,然后把它修改成如下代码:

#修改成mysql如下:
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'test',    #你的数据库名称
        'USER': 'root',   #你的数据库用户名
        'PASSWORD': '445813', #你的数据库密码
        'HOST': '', #你的数据库主机,留空默认为localhost
        'PORT': '3306', #你的数据库端口
    }}


#由于mysql默认引擎为MySQLdb,在myblog下的__init__.py文件中添加下面代码

import pymysql
pymysql.version_info = (1, 4, 6, 'final', 0)  # change mysqlclient version,because python version is 3.7 and pymysql version is 0.93
pymysql.install_as_MySQLdb()
#如果找不到pymysql板块,则通过pip install pymysql进行安装。

3、数据库设置好之后,我们就依次输入下面的命令进行数据库迁移:

	python manage.py makemigrations
	python manage.py migrate

迁移的时候,会有如下提示:
在这里插入图片描述
出现这个原因是因为我们的幻灯图使用到图片字段,我们需要引入图片处理包。提示里也给了我们处理方案,输入如下命令,安装Pillow模块即可:
pip install Pillow
安装成功之后再迁移数据库
在这里插入图片描述
数据库迁移成功之后,程序会在blog下的migrations目录里自动生成几个000开头的文件,文件里面记录着数据库迁移记录
在这里插入图片描述在这里插入图片描述

二、用Admin管理后台管理数据

点击Pycharm右上角的Database,然后在网站项目里选中我们的数据库文件db.sqlite3,把它拖到Database框里。
在这里插入图片描述
但是没有数据。刷新会报错。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
Pycharm Batabase限制非常大,下面我们介绍如何使用Django自带的admin管理网站数据。django的admin后台管理它可以让我们快速便捷管理数据,我们可以在各个app目录下的admin.py文件中对其进行控制。

想要对APP应用进行管理,最基本的前提是要先在settings里对其进行注册,就是在INSTALLED_APPS里把APP名添加进去,我们在前面的文章有提到过。

注册APP应用之后,我们想要在admin后台里对数据库表进行操作,我们还得在应用APP下的admin.py文件里对数据库表先进行注册。我们的APP应用是blog,所以我们需要在blog/admin.py文件里进行注册:

from django.contrib import admin
# Register your models here.
from .models import Banner, Category, Tag, Tui, Article, Link

#导入需要管理的数据库表

@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
    list_display = ('id', 'category', 'title', 'tui', 'user', 'views', 'created_time')
    # 文章列表里显示想要显示的字段
    list_per_page = 50
    # 满50条数据就自动分页
    ordering = ('created_time',)
    #后台数据列表排序方式
    list_display_links = ('id', 'title')
    # 设置哪些字段可以点击进入编辑界面

@admin.register(Banner)
class BannerAdmin(admin.ModelAdmin):
    list_display = ('id', 'text_info', 'img', 'link_url', 'is_active')

@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
    list_display = ('id', 'name', 'index')

@admin.register(Tag)
class TagAdmin(admin.ModelAdmin):
    list_display = ('id', 'name')

@admin.register(Tui)
class TuiAdmin(admin.ModelAdmin):
    list_display = ('id', 'name')

@admin.register(Link)
class LinkAdmin(admin.ModelAdmin):
    list_display = ('id', 'name','linkurl')

登录管理后台http://127.0.0.1:8000/admin/

注册后的后台:
在这里插入图片描述
多出了之前我们在models里创建的表。我们可以在后台里面对这些表进行增、删、改方面的操作。

三、使用富文本编辑器添加数据

在Django admin后台添加数据的时候,文章内容文本框想发布一篇图文并茂的文章需就得手写Html代码,这十分吃力,也没法上传图片和文件。
在这里插入图片描述

  1. 首先我们先下载DjangoUeditor包。点击下面的链接进行下载!下载完成然后解压到项目根目录里。
    DjangoUeditor.zip
  2. settings.py里注册APP,在INSTALLED_APPS里添加’DjangoUeditor,’。
#myblog/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'blog.apps.BlogConfig',
    'DjangoUeditor', #注册富文本编辑器APP应用
]
  1. myblog/urls.py里添加url。
#myblog/urls.py
from django.urls import path, include
#留意上面这行比原来多了一个include

urlpatterns = [
    path('admin/', admin.site.urls), 
    path('ueditor/', include('DjangoUeditor.urls')), #添加DjangoUeditor的URL
]
  1. 修改blog/models.py里需要使用富文本编辑器渲染的字段。这里面我们要修改的是Article表里的body字段。

把原来的:blog/models.py

body = models.TextField()

修改成:blog/models.py

from DjangoUeditor.models import UEditorField #头部增加这行代码导入UEditorField

body = UEditorField('内容', width=800, height=500, 
                    toolbars="full", imagePath="upimg/", filePath="upfile/",
                    upload_settings={"imageMaxSize": 1204000},
                    settings={}, command=None, blank=True
                    )

留意里面的imagePath=“upimg/”, filePath=“upfile/” 这两个是图片和文件上传的路径,我们上传文件,会自动上传到项目根目录media文件夹下对应的upimg和upfile目录里,这个目录名可以自行定义。有的人问,为什么会上传到media目录里去呢?那是因为之前我们在基础配置文章里,设置了上传文件目录media。

上面步骤完成后,我们启动项目,进入文章发布页面。提示出错:

render() got an unexpected keyword argument 'renderer'

错误图片如下:
在这里插入图片描述
错误页面上有提示,出错的地方是下面文件的96行。打开这个文件的93行,注释这行即可。
在这里插入图片描述
修改成之后,重新刷新页面,就可以看到我们的富文本编辑器正常显示。
在这里插入图片描述
留意,如果我们在富文本编辑器里,上传图片,在编辑器内容里不显示上传的图片。那我们还需要进行如下设置,打开myblog/urls.py文件,在里面输入如下代码:

#myblog/urls.py
....
from django.urls import path, include, re_path
#上面这行多加了一个re_path
from django.views.static import serve
#导入静态文件模块
from django.conf import settings
#导入配置文件里的文件上传配置

urlpatterns = [
    path('admin/', admin.site.urls),
    ....
    re_path('^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}),#增加此行
]

设置好了之后,图片就会正常显示。这样我们就可以用DjangoUeditor富文本编辑器发布图文并茂的文章了。

四、URL与视图函数

1.请求响应过程

请求响应过程:
浏览器->发送HTTP请求到——服务器——处理请求->返回HTTP响应——HTML->浏览器

2.Pycharm中的Django项目URL映射

1.app的url映射默认为下图:在这里插入图片描述
规则说明:

urlpatterns = [
    path(正则表达式, views视图函数,参数,别名),
]

括号里的参数说明:
1、一个正则表达式字符串
2、一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串
3、可选的要传递给视图函数的默认参数(字典形式)
4、一个可选的name参数(别名)

每个URL都对应一个views视图函数名,视图函数名不能相同,否则会报错。视图函数,Django中约定写在APP应用里的views.py文件里。然后在urls.py文件里通过下面的方式导入:

from APP应用名 import views
from APP应用名.vews import 函数名或类名

视图函数是一个简单的Python 函数,它接受Web请求并且返回Web响应。响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片. . . 是任何东西都可以。无论视图本身包含什么逻辑,都要返回响应。这个视图函数代码一般约定是放置在项目或应用程序目录中的views.py的文件中。
http请求中产生两个核心对象:
1、http请求---->HttpRequest对象,用户请求相关的所有信息(对象)
2、http响应---->HttpResponse对象,响应字符串

3.简单测试

打开打开bolg目录下的views.py文件,写一个hello视图函数,在里面输入:

from django.http import HttpResponse

def hello(request):
"""
写一个hello函数,通过request接收URL或者说是http请求信息,
然后给这个请求返回一个HttpResponse对象
"""
return HttpResponse('欢迎使用Django!')

request,就是HttpRequest对象。HttpResponse(“欢迎使用Django!”),就是HttpRequest对象,它向http请求响应了一段字符串对象。
我们打开myblog目录下的urls.py文件中先导入视图函数,然后构造一个URL,代码如下:

from blog import views  #导入视图函数
urlpatterns = [
    ...
    path('', views.hello),   #这个是我们构造的URL
]

代码写完之后,启动项目就可以在浏览器里看到视图函数返回的字符串"欢迎使用Django!"

4.Django请求生命周期

通过URL对应关系匹配 ->找到对应的函数(或者类)->返回字符串(或者读取Html之后返回渲染的字符串)这个过程也就是我们Django请求的生命周期。
视图函数,就是围绕着HttpRequest和HttpResponse这两个对象进行的。

五、django模板

1.概念

视图会返回一个响应,响应可以是一个HTML内容的网页。我们把这样的页面按规范写好,然后都放在项目根目录下的templates文件夹里,这样的页面,我们称之为"模板"页面。

模板页面包含一些基础的HTML代码和一些特殊的语法,这些特殊的语法主要用于如何将数据动态的插入HTML页面中。

这些特殊的语法我们把它做变量、标签。变量是模板中最基本的组成单位。这些模板变量由视图函数生成的,然后通过上下文传递到模板里,然后由浏览器渲染出来。

2.变量

  1. 在文件myblog/urls.py里设置一个URL:

    #myblog/urls.py
    urlpatterns = [

    path(’’, views.index), #’'留空,表示为首页

    ]

  2. 在文件blog/views.py里添加一个视图函数:

    blog/vews.py

    #添加一个函数
    def index(request):
    #添加两个变量,并给它们赋值
    sitename = ‘小小百度’
    url = ‘www.baidu.com’
    #把两个变量封装到上下文里
    context = {
    ‘sitename’: sitename,
    ‘url’:url,
    }
    #把上下文传递到模板里
    return render(request,‘index.html’,context)

  3. 在项目根目录下templates文件夹里新建一个文件index.html,输入如下内容:

     #templates/index.html
     
     <!DOCTYPE html>
     <html lang="en">
     <head>
         <meta charset="UTF-8">
         <title>MyBlog</title>
     </head>
     <body>
     <h3>网站名:{{ sitename }}</h3>
     <h3>域名:{{ url }}</h3>
     </body>
     </html>
    
  4. Terminal窗口输入运行

    python manage.py runserver
    在这里插入图片描述

2.列表+字典显示

  1. 在视图函数里添加如下代码:

     from django.shortcuts import render
    
     # Create your views here.
    
     #添加一个函数
     def index(request):
         #添加两个变量,并给它们赋值
         sitename = '小小百度'
         url = 'www.baidu.com'
         # 新加一个列表
         myList = [
             '鲁菜',
             '川菜',
             '粤菜',
             '苏菜',
             '浙菜',
             '闽菜',
             '湘菜',
             '徽菜',
         ]
         # 在上面基础上新加一个字典
         mydict = {
             'name': '企鹅',
             'qq': '111111111',
             'wx': '111111111',
             'email': '573690349@qq.com',
             'Q群': '11111111',
         }
         #把四个变量封装到上下文里
         context = {
             'sitename': sitename,
             'url':url,
             'myList': myList,  # 把myList封装到context
             'mydict': mydict,  # 把mydict封装到context
     
         }
         #把上下文传递到模板里
         return render(request,'index.html',context)
    
  2. 在项目根目录下templates文件夹里文件index.html,输入如下内容:

     <!DOCTYPE html>
         <!--myblog/templates/index.html-->
         <html lang="en">
         <head>
             <meta charset="UTF-8">
             <title>MyBlog</title>
         </head>
         <body>
         <h3>网站名:{{ sitename }}</h3>
         <h3>域名:{{ url }}</h3>
         {#新下面的代码#}
         <div>
             <ul>
             <h4>八大菜系:</h4>
                 {% for item in myList  %}
                 <li>{{ item }}</li>
                 {% endfor %}
             </ul>
         </div>
         <!-- 新加如下代码 -->
         <div>
             <ul>
             <h4>Blog教程作者信息:</h4>
                 {% for key,values in mydict.items  %}
                 <li>{{ key }}:{{ values }}</li>
                 {% endfor %}
             </ul>
         </div>
         </body>
     </html>
    
  3. Terminal窗口输入运行

     python manage.py runserver
    

六.数据查询

  1. 从models.py里导入模型Product(也就是类名,或者说表名):

     #blog/views.py
     #比如我信要查询所有文章,我们就要views.py文件头部把文章表从数据模型导入
     from .models import Article
    
  2. 在视图函数里对要查询的Product进行声明并实例化,然后生成对象allarticle。

     #blog/views.py
     
     def index(request):
         #对Article进行声明并实例化,然后生成对象allarticle
         allarticle = Article.objects.all()
         #把查询到的对象,封装到上下文
         context = {
             'allarticle': allarticle,
         }
         #把上传文传到模板页面index.html里
         return render(request,'index.html',context)
     注:这里我在原来的基础上,把index视图函数里的内容删除了,修改成上面的内容,下面的模板页面index.html也是如此。
    
  3. 打开templates/index.html页面,修改成下面的内容:

     <!DOCTYPE html>
     <html lang="en">
     <head>
         <meta charset="UTF-8">
         <title>MyBlog</title>
     </head>
     <body>
     
     <div>
         <ul>
         <h4>所有文章:</h4>
             {% for article in allarticle  %}
             <li>{{ article.title }}</li>
             {% endfor %}
         </ul>
     </div>
     
     </div>
     </body>
     </html>
    

然后访问网站首页。就能看到我们的查询结果。

在模板里,我们可以对对象的属性进行赋值。比如模板里的{{ article.title }} 标题,就是我们通过{{ 对象.属性(字段) }}获取到对应的值。其它字段也是通过这样的方法来实现。

例如:

<!DOCTYPE html>
    <!--myblog/templates/index.html-->
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>MyBlog</title>
    </head>
    <body>
    <h3>网站名:{{ sitename }}</h3>
    <h3>域名:{{ url }}</h3>
    {#新下面的代码#}
    <div>
        <ul>
        <h4>八大菜系:</h4>
            {% for item in myList  %}
            <li>{{ item }}</li>
            {% endfor %}
        </ul>
    </div>
    <!-- 新加如下代码 -->
    <div>
        <ul>
        <h4>个人信息:</h4>
            {% for key,values in mydict.items  %}
            <li>{{ key }}:{{ values }}</li>
            {% endfor %}
        </ul>
    </div>
    <div>
	    <ul>
	    <h4>所有文章:</h4>
	        {% for article in allarticle  %}
	        <li>
	            标题:{{ article.title }}<br />
	            栏目:{{ article.category }}<br />
	            作者:{{ article.user }}<br />
	            时间:{{ article.created_time }}<br />
	        </li>
	        {% endfor %}
	    </ul>

	</div>
    </body>
</html>

从之前的文章我们可以看到,如果我们想要将数据库的数据展现到网页上,需要由视图、模型与模板共同实现,步骤如下:

  1. 在models.py里定义数据模型,以类的方式定义数据表的字段。在数据库创建数据表时,数据表由模型定义的类生成。

  2. 在视图views.py导入模型所定义的类,我们把这个类称之为数据表对象,然后在视图函数里使用Django的数据库操作方法,实现数据库操作,从而获取到数据表里的数据。

  3. 视图函数获取到数据之后,将数据以字典、列表或对象(上下文context)的方式传递给HTML模板,并由模板引擎接收和解析,最后生成相应的HTML网页,在浏览器里展现出来。

点击下载本文代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值