Python+Django搭建个人博客(5)-Django模型

认识数据库

  • 存储数据的仓库
  • 什么是数据?
    • 学生的姓名、性别、成绩;
    • 用户的银行卡号、密码、余额、交易记录
    • 网站的登录账号、密码、评论
    • 游戏的用户名、装备、属性、等级

数据是如何存在数据库中

  • 一张张表存储各种信息

  • 表与表之间还可能有不同的联系

    image
    image

Django中的数据库

  • 打开blog应用里的models.py文件

  • 加入以下内容

    #继承于models.Model, 新建了叫post的表格
    class Post(models.Model):
    
        # 有title属性
        title=modesl.CharField(max_length=80)
    
  • 同步数据库

    • 根目录运行python manage.py makemigrations
    • 得到如下提示,表示创建了Post模型


      image
    • 继续命令运行python manage.py migrate
    • 得到如下提示


      image

利用admin后台系统管理数据

  • 运行python manage.py runserver启动服务器

  • 修改blog文件夹中的admin.py

    from django.contrib import admin
    from .models import Post
    
    # Register your models here.
    admin.site.register(Post)
    
  • 登录admin后台系统

    • 访问http://127.0.0.1:8000/admin,会看到新增了一个栏目

      image
  • admin后台系统管理

    • 点击Posts进入,可以看见还没有内容发布过

    • 点击ADD POST,可直接添加一个Post的title


      image
    • 在title中输入内容,SAVE保存,保存后叫Post project(1),不直观

    • 修改blog文件夹里的models.py

      class Post(models.Model):
      
      # 有title属性
      title=models.CharField(max_length=80)
      
      def __str__(self):
              return self.title
      

      此时,这里就展示的是你输入的title的内容

      image

设计博文模型

  • 一篇博客相关的信息如下:

    • 标题
    • 副标题
    • 作者
    • 发表日期
    • 标签
    • 分类
    • 博文内容
    • 博文链接
    • 点赞数(可选)
    • 阅读量(可选)
  • Django中可用的各类模型

    image

    目前常用:
    - CharField 简单文字模型
    - DateTiemField 时间模型
    - TextField 大段文字模型

  • 设计博文模型简易版

    image

    这样设计存在什么问题?

    作者、标签、分类存在同一个表中,会造成大量重复的内容、不易检索、不易修改。

    image
  • 设计博文模型进阶版

    image

博文基础模版

  • models.py添加一些基础模型

    class Post(models.Model):
    
        title=models.CharField(max_length=80)
        subtitle=CharField(max_length=120)
        publish_date=models.DateTimeField()
        content=models.TextField()
        link=models.CharField(max_length=200)
    
        def __str__(self):
                return self.title
    
  • 关联作者模型

    from django.db import models
    from django.contrib.auth.models import User`
    
    class Post(models.Model):
    
    title=models.CharField(max_length=80)
    subtitle=CharField(max_length=120)
    publish_date=models.DateTimeField()
    content=models.TextField()
    link=models.CharField(max_length=200)
    # 利用ForeignKey()即把字段author关联另外一个模型
    author=models.ForeignKey(User,on_delete=models.CASCADE) 
    
    def __str__(self):
            return self.title
    

新建分类模型和标签模型

添加两个class,同时补充Post类

class Category(models.Model):
    """分类"""
    name = models.CharField(max_length=100)
    def __str__(self):
            return self.name

class Tag(models.Model):
    """标签"""
    name = models.CharField(max_length=100)
    def __str__(self):
            return self.name

class Post(models.Model):
    title=models.CharField(max_length=80)
    subtitle=models.CharField(max_length=120)
    publish_date=models.DateTimeField()
    content=models.TextField()
    link=models.CharField(max_length=200)
    # 利用ForeignKey()即可关联另外一个模型
    author=models.ForeignKey(User,on_delete=models.CASCADE) 
    category=models.ForeignKey(Category,on_delete=models.CASCADE) 
    # 利用MangToManyField()关联另外一个模型
    tag=models.ManyToManyField(Tag,blank=True)

    def __str__(self):
            return self.title
  • ForeignKey()和ManyToManyField()的区别

    • 一对多的关系,使用ForeignKey()

      一篇文章只有一个分类,一个分类下有多个文章

      image
    • 多对多的关系,使用MangToManyField()

      一个文章可以有多个标签,一个标签会对应多个文章


      image
  • 新建了2个模型,所以要在admin.py中添加

    from django.contrib import admin
    from .models import Post
    from .models import Category
    from .models import Tag
    
    # Register your models here.
    
    admin.site.register(Category)
    admin.site.register(Tag)
    admin.site.register(Post)
    

运行Django的管理命令

  • 只要修改了models.py文件,都需要运行python manage.py makemigrations

    会提示:


    image

    意思为:

    image

    选择1方案,填写默认值1,除了时datetime填timezone.now

    创建成功:

    image
  • 每次运行完python manage.py makemigrations,都要运行python manage.py magrate

  • 注意:如果这里运行python manage.py magrate时一直报错,难以结局,可以尝试删掉my_blog下的db.sqlite3文件,再重新运行python manage.py magrate,再重新创建admin账号即可。

admin后台查看

  • 进入到后台管理,可以看到新增了Category、Tag

    image
  • 点击Posts-Add post,新增了我们写的字段

    image
  • 添加Category,比如添加编程分类

![image](https://upload-images.jianshu.io/upload_images/12041448-3c7cf803756c4e3d?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
  • 添加Tag,比如添加Python标签

    image
  • 再进入到post,可以发现Category可选编程,Tag可以选Python,直接点击添加也可

    image

从数据库提取真正的博文信息

  • 修改views.py
    • 引入Post模型
      from .models import Post

    • 列出全部的Post数据,按发表日期倒序排列
      Post.objects.all().order_by('-publish_date')

    • 修改如下:

      from django.shortcuts import render
      from django.http import HttpResponse
      from .models import Post
      
      # Create your views here.
      
      def index(request):
          post_list=Post.objects.all().order_by('-publish_date')
          return render(request,'blog/index.html',{'post_list':post_list})
      

设计博客详情页网址

  • 每篇博文有一个英文的网址,如127.0.0.1:8080/blog/django-course-1

  • 后台link只需要填django-course-1部分

  • 修改index.html的博客详情页链接,设计为blog/link

    <a href="/blog/{{post.link}}">

  • 将时间那里改为我们的时间变量

    <p class="post-meta">Posted by
            <a href="#">{{post.author}}</a>
            {{post.publish_date}}</p>
    
  • 修改urls.py的网址配置,将blog_detail的参数改为blog_link
    path('<int:blog_link>',views.blog_detail,name='blog_detail'),

  • 修改views.py
    from django.shortcuts import render,get_object_or_404

    get_object_or_404表示从某个模型根据关键字提取某段数据,找不到返回数据,就返回404页面

    def blog_detail(request,blog_link):
        post=get_object_or_404(Post,link=blog_link)
        return HttpResponse(post.content)
    
  • 在管理后台配置一篇博客,看下效果

    image
    image

添加博客详情页模版

我们下载的模版中,有一个post.html的文件,就是我们博客详情页的模版,把它用到我们项目中,放在我们app的/templates/blog下.

  • 修改views.py

    def blog_detail(request,blog_link):
    
        post=get_object_or_404(Post,link=blog_link)
        # 返回博文详情
        return render(request,'blog/post.html',{'post':post})
    
  • 修改post.html

    同我们修改index.html一样,把js、css、img的路径进行修改:

    <link href="{%static 'blog/vendor/bootstrap/css/bootstrap.min.css' %}" rel="stylesheet">

    修改title、标题、副标题、作者、正文、时间:

![image](https://upload-images.jianshu.io/upload_images/12041448-80c6cf86d6389b21?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


![image](https://upload-images.jianshu.io/upload_images/12041448-c1880a0405574a05?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


![image](https://upload-images.jianshu.io/upload_images/12041448-e98dde80a216caf5?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

更漂亮的正文排版

方式一:在后台的content中直接写html代码,比较麻烦;

方式二:采用Markdown格式编写博文(推荐)

  • 安装markdown模块 pip install markdown2
  • 修改views.py
    def blog_detail(request,blog_link):
    
        post=get_object_or_404(Post,link=blog_link)
        post.content = markdown2.markdown(post.content)
        # 返回博文详情
        return render(request,'blog/post.html',{'post':post})
    
  • 后台博客content中用markdown语法进行编辑
![image](https://upload-images.jianshu.io/upload_images/12041448-a186b0859874f986?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

![image](https://upload-images.jianshu.io/upload_images/12041448-065707266d6d84c6?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

发现没有对标签进行渲染,如何解决?

在post.html中的`{{post.content}}`修改为`{{post.content|safe}}`

![image](https://upload-images.jianshu.io/upload_images/12041448-2662420cd0abf804?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

    
![image](https://upload-images.jianshu.io/upload_images/12041448-6951cad5b72d5aec?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

**遗留问题,这里貌似不支持代码块的展示,待解决**

调整url

现在的url是127.0.0.1:8000/blog/首页,我们希望127.0.0.1:8000就是首页

  • 修改my_blog的urls.py
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('',include('blog.urls')),
    ]
    
  • 修改blog的urls.py
    urlpatterns = [
        path('',views.index,name='blog_index'),
        path('blog/<slug:blog_link>/',views.blog_detail,name='blog_detail'),
    ]
    

如何把网站对外发布

  • 购买服务器和域名
    • 服务器见文章最前面部分

    • 域名

      • 国内:wanwang.aliyun.com
      • 国外:godaddy.com
      • .cn/.com等域名需要实名认证
    • 服务器或者域名在国内买的,需要进行备案,没有备案的话,有可能会被墙掉

    • 购买后,设置域名解析,表示该域名指向的服务器ip地址

      image

Django部署

(不详细讲,自行google)

  1. 安装uwsgi

  2. 配置uwsgi.ini

    示例:

    image
  3. 安装nginx

  4. 配置nginx

  5. 启动uwsgi uwsgi --ini uwsgi.ini

  6. 启动nginx

服务器使用中常见的几个问题

image
  1. 可能是数据库没有填写我们的hosts
  2. 80端口可能之前已经被打开,关掉80端口即可
  3. ip地址没填对,要公网的ip地址
  4. 连上一段时间没有操作也会自动断掉
  5. 网络连接问题
  6. 安装一个screen应用

作业

image
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容