Django - 模型

Posted xuanlv-0413

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django - 模型相关的知识,希望对你有一定的参考价值。

我个人对django中ORM的实现的理解:在models中写好类,通过migrate写入数据库。接着使用django封装好的方法,进行传参、调用。

一、数据库配置

(一).在settings.py中配置DATABASES

技术分享图片
DATABASES = {
    default: {
        ENGINE: django.db.backends.mysql,  # 数据库引擎
        NAME: mydb,  # 数据库名称
        USER: root,  # 连接数据库的用户名
        PASSWORD: qwe123,  # 连接数据库的密码
        HOST: 127.0.0.1,  # mysql服务器的域名和ip地址
        # ‘USER‘: ‘admin‘,
        # ‘PASSWORD‘: ‘Root110qwe‘,
        # ‘HOST‘: ‘192.168.72.130‘,
        PORT: 3308,  # mysql的一个端口号,默认是3306
    }
}
View Code

注意事项:

(1).只要"HOST"不为127.0.0.1的时候,对于MySQL的root来说,都是属于远程连接(填写虚拟机中Linux的IP也算远程了)

而root用户只能在本地使用,它是拒绝远程连接的。所以,不填写127.0.0.1的话,可以考虑使用与root同权限的用户进行连接。

(2).NAME中所指定的数据库,一定要事先建好!数据库都没有,你让django怎么去连?连哪个?Ps:这是MySQL,不是MongoDB

(二).安装数据库连接器

在你自己使用的那个环境中,pip install pymsql

(三).在主目录下的的__init__.py文件添加下面两句

技术分享图片
import pymysql
pymysql.install_as_MySQLdb()
View Code

二、使用django中的模型

(一).进入你的app,打开"models.py"

最简单的示例1:

技术分享图片
# blog/models.py
from django.db import models
# Create your models here.

class User(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=30)
    age = models.IntegerField()
    
    def __str__(self):
        return User<id=%s,name=%s,age=%s>%(
            self.id,self.name,self.age)
View Code

注意事项:

(1).模型必须都写在app的models.py中。

(2).模型所属的app必须被注册到"settings.py"的"INSTALL_APPS"中去,不然下面(二)的时候,是映射不到数据库中去的。

(3).所有的类,都必须继承"models.Model"才能生成映射后的表格。

(4).一个数据表对应模型中的类名。表中的字段,对应模型中的类属性。

(5).字段是varchar类型的话(它对应的是CharField),必须在CharField中设置max_length的值,不然会报错。

(6).AutoField()可以不写,django也会为我们自动创建。

(二).将模型映射到数据库中

(1).首先要创建一个映射文件

进入"manage.py"这个文件所在的目录,敲命令:python manage.py makemigrations

(2).将映射文件中的映射数据真正提交到数据库中

敲命令:python manage.py migrate

(3).两个命令长相差不多,一开始傻傻分不清,咋记?

migration是名词,所以只是个映射文件。migrate是动词,[/动起来~],才会真正起作用了。

(三).添加新字段的方式

有新字段要增加了?不用去MySQL中敲那么长一大段代码了,直接在django中进行操作就行。[/窃窃私语]:MySQL原生态添加新字段的代码真心很长 — —!

(1).直接点开models.py,把你想要加的字段,写进对应的类中

注意:新的字段需要指定"null=True"或者也可以用"default=‘xxx‘"来代替。这两个你要是一个都不写,migration就会报错!因为原来的字段已经存在于数据表中了,数据表中可能已有数据了。那你这个新字段的值是什么?什么都没有,那不就报错了。

技术分享图片

(2).cd到"manage.py"这个文件所在的目录中。

(3).再次执行命令:

技术分享图片
python manage.py makemigrations
# 等它执行完

# 新增字段会让你确认。直接输入 y 回车

# 再执行
python manage.py migrate
View Code

(四).修改字段

发现字段写错了?参考(三)同理可得

技术分享图片

再次执行migrations和migrate

 

三、数据的增删改查

(一).增(add)

技术分享图片
# blog/views.py
from .models import User
def add_user(request):
    # 方法一:
    # tiazi = User(name=‘tiazi‘,age=18)
    # tiazi.save()
    # 方法二:
    # xm = User()
    # xm.name = ‘xiaoming‘
    # xm.age = 19
    # xm.save()
    # 方法三:
    # User.objects.create(name=‘xiaohong‘,age=20,)
    # 方法四:
    User.objects.get_or_create(name=xiaohua,age=21)
    return HttpResponse(插入数据成功!!!)
View Code

(1).字段编码有问题该如何处理

当带有汉字的数据记录插入表时报错了,基本是属于表的编码没有设置好,执行下面的代码

技术分享图片
alter table 数据表名 CONVERT TO CHARACTER SET utf8;
View Code

(二).删(delete)

在MySQL中,我已写了老师曾说过一段话:“在开发中,有个不成文的规矩:宁可让数据作废,也不要去删”

我个人比较认可,万一你删错了呢?哪怕是测试用的数据,删错了,不是给自己找麻烦!

技术分享图片
# blog/views.py
def delete_user(request):
    User.objects.get(id=1).delete()
    return HttpResponse(删除数据成功!!!)
View Code

(三).改(update)

技术分享图片
# blog/views.py
def update_user(request):
    # rs = User.objects.get(name=‘xiaoming‘)
    # rs.name = ‘Xiaoming‘
    # rs.save()
    # User.objects.filter(name=‘Xiaoming‘).update(name=‘XM‘)
    User.objects.all().update(city=zhangsan)
    return HttpResponse(更新数据成功!!!)
View Code

(四).查(selcet)

技术分享图片
# blog/views.py
def search_user(request):
    # 查询所有记录对象
    # rs = User.objects.all()
    # 查询一个记录对象
    # rs = User.objects.get(id=1)
    # 获取满足条件的对象
    rs = User.objects.filter(name=xiaoming)
    print(rs)
    return HttpResponse(查询数据成功!!!)
View Code

(1).常用的查询

技术分享图片
获取所有记录:
rs = User.objects.all()

获取第一条数据:
rs = User.objects.first()

获取最后一条数据:
rs = User.objects.last()

根据参数提供的条件获取过滤后的记录:
rs = User.objects.filter(name=xiaoming)
注意:filter(**kwargs)方法:根据参数提供的提取条件,获取一个过滤后的QuerySet。

排除name等于xiaoming的记录:
rs = User.objects.exclude(name=xiaoming)

获取一个记录对象:
rs = User.objects.get(name=xiaoming)
注意:get返回的对象具有唯一性质,如果符合条件的对象有多个,则get报错!

对结果排序order_by:
rs = User.objects.order_by(age)

多项排序:
rs = User.objects.order_by(age,id)

逆向排序:
rs = User.objects.order_by(-age)

将返回来的QuerySet中的Model转换为字典
rs = User.objects.all().values()

获取当前查询到的数据的总数:
rs = User.objects.count()
View Code

(2).常用的查询对象的条件参数

技术分享图片
查找对象的条件的意思是传给以上方法的一些参数。相当于是SQL语句中的where语句后面的条件,语法为"字段名__规则",以下将对这些规则进行说明:

exact 相当于等于号:
rs = User.objects.filter(name__exact=xiaoming)
iexact:跟exact,只是忽略大小写的匹配。

contains 包含:
rs = User.objects.filter(name__contains=xiao)
icontains 跟contains,唯一不同是忽略大小写。

startwith 以什么开始:
rs = User.objects.filter(name__startswith=xiao)
istartswith:同startswith,忽略大小写。

endswith:同startswith,以什么结尾。
iendswith:同istartswith,以什么结尾,忽略大小写。

in 成员所属:
rs = User.objects.filter(age__in=[18,19,20])

gt 大于:
rs = User.objects.filter(age__gt=20)
gte 大于等于:
rs = User.objects.filter(age__gte=20)

lt 小于:
rs = User.objects.filter(age__lt=20)
lte 小于等于:
rs = User.objects.filter(age__lte=20)

range 区间:
rs = User.objects.filter(age__range=(18,20))

isnull 判断是否为空:
rs = User.objects.filter(country__isnull=True)

切片:
rs = User.objects.all()[:2]
注意:不能使用负数作为切片。
View Code

(五).注意事项

(1).filter()返回一个查询集合(可以视作列表)

(2).get()只返回一个对象,没有对象返回会报错(类名.DoesNotExist)

 

四、常用的模型字段类型

(一).IntegerField

整型,映射到数据库中的int类型。

(二).CharField

字符类型,映射到数据库中的varchar类型。必须制定max_length的值,不然就报错。

(三).TextField

文本类型,映射到数据库中的text类型。

(四).BooleanField

布尔类型,映射到数据库中的tinyint类型,在使用的时候,传递True/False进去。如果要可以为空,则用NullBooleanField。

(五).DateField

日期类型,没有时间。映射到数据库中是date类型,

在使用的时候,可以设置DateField(auto_now=True)每次修改对象时,自动设置该字段为当前时间。

设置DateField(auto_now_add=True)当对象第一次被创建时自动设置当前时间。

注意:DateField(auto_now=True)只有调用Model.save()方法才会调用,QuerySet.update方法将不会调用。这个参数只是Date和DateTime以及Time类才有的。

(六).DateTimeField

日期+时间类型。映射到数据库中的是datetime类型,在使用的时候,传递datetime.datetime()进去。

同样可以设置auto_now_add和auto_now

(七).补充

(1).关于django时区的问题

此博主总结得挺好:https://www.cnblogs.com/alan-babyblog/p/5739004.html

如果要使用本地时间,设置这两个属性:TIME_ZONE="Asia/Shanghai"; USE_TZ=False

(2).修改MySQL的时区

用root用户进入MySQL中,直接敲命令:set time_zone=‘+8:00‘;

然后重启MySQL服务:sudo service mysqld restart

再次进入MySQL中,查看时间的命令:select now();

 

五、表关系的实现

(一).一对多表关系

在MySQL中一对多是通过外键实现的,在django模型中通过ForeignKeyField类型实现。

(二).一对一表关系

在Mysql中一对一是通过外键+唯一键实现的,在django模型中通过OneToOneField类型实现。

(三).多对多表关系

在MySQL中多对多是通过中间表外键+联合唯一键实现的,在django模型中通过ManyToManyField类型实现。中间表模型会自动帮我们创建好。

(四).示例

(1).在app中的models.py中写好类

技术分享图片
class Department(models.Model):
    d_id = models.AutoField(primary_key=True)
    d_name = models.CharField(max_length=30)
    def __str__(self):
        return Department<d_id=%s,d_name=%s>%(
            self.d_id,self.d_name
        )


class Student(models.Model):
    s_id = models.AutoField(primary_key=True)
    s_name = models.CharField(max_length=30)
    department = models.ForeignKey(Department)
    course = models.ManyToManyField(Course)
    def __str__(self):
        return Student<s_id=%s,s_name=%s>%(
            self.s_id,self.s_name
        )


class Course(models.Model):
    c_id = models.AutoField(primary_key=True)
    c_name = models.CharField(max_length=30)
    def __str__(self):
        return Course<c_id=%s,c_name=%s>%(
            self.c_id,self.c_name
        )


class Stu_detail(models.Model):
    s_id = models.OneToOneField(Student)
    age = models.IntegerField()
    gender = models.BooleanField(default=1)
    country = models.CharField(max_length=30,null=True)
    def __str__(self):
        return Stu_detail<s_id=%s,age=%s,gender=%s,country=%s>%(
            self.s_id,self.age,self.gender,self.country
        )
View Code

(2).分别执行

python manage.py makemigrations App_name

python manage.py migrate App_name

(3).在视图中对关系表的操作

技术分享图片
from .models import Department,Student,Course

def add_info(request):
    # d1 = Department(d_name=‘AA‘)
    # d1.save()
    # 一对多关系加内容
    # s1 = Student(s_name=‘xiaoming‘)
    # s1.department = d1
    # s1.save()
    # 多对多关系添加内容
    # c1 = Course(c_name=‘python‘)
    # s1 = Student.objects.first()
    # c1.save()
    # s1.course.add(c1)
    return HttpResponse(添加数据成功)
    
def search_info(request):
    rs = Student.objects.all()[0]
    # 一对多的查询
    print(rs.department)
    # 多对多的正向查询
    print(rs.course.all())
    cs = Course.objects.first()
    # 多对多反向查询
    print(cs.student_set.all())
    return HttpResponse(查询数据成功)
View Code

(4).前向查询

如果一个模型有ForeignKey(),那么该模型的实例可以通过属性访问的方式,去访问关联的(外部)对象。

技术分享图片
s1 = Student.objects.get(s_id=1)
print(s1)
# <Student: Student<s_id=1,s_name=xiaoming>>
print(s1.department)
# <Department: Department<d_id=6,d_name=AA>>

# 还可以通过外键属性获取和设置
dx = Department.objects.get(d_id=3)
print(dx)
# <Department: Department<d_id=3,d_name=设计>>
s1.department = dx
print(s1.department )
# <Department: Department<d_id=3,d_name=设计>>
s1.save()  # 一定要save()了才会保存到数据库
View Code

(5).反向查询,方式1

模型类中有ForeignKey(),那么那么可以通过"类名.modelname_set"的方式获取值。

例如:

技术分享图片
d1 = Department.objects.get(d_id=1)
print(d1)
# <Department: Department<d_id=1,d_name=软件>>
print(d1.student_set.all())
"""
<QuerySet [<Student: Student<s_id=2,s_name=xiaohong>>, <Student: Student<s_id=3,s_name=xiaohua>>, <Student: Student<s_id=4,s_name=xiaoxin>>, <Student: Student<s_id=5,s_name=小明>>]>
"""
View Code

(6).反向查询,方式2

可以在ForeignKey()定义时,在小括号里设置related_name这个参数,例如设置成:related_name="student"

这个related_name参数会覆盖modelname_set的名称。

把Student模型改成department=models.ForeignKey(‘Department‘,related_name=‘student‘),那么上面的示例代码应该改成这样:

技术分享图片
from blog.models import Student,Department,Course

d1 = Department.objects.get(d_id=1)
print(d1.student.all())
"""
<QuerySet [<Student: Student<s_id=2,s_name=xiaohong>>, <Student: Student<s_id=3,s_name=xiaohua>>, <Student: Student<s_id=4,s_name=xiaoxin>>, <Student: Student<s_id=5,s_name=小明>>]>
"""
View Code

六、处理关联对象的其它方法

(一).add(obj1, obj2, ...)

添加一指定的模型对象到关联的对象集中。(一对多,多对多)。使用这个add的前提是要数据库中已经有的数据。

技术分享图片
d1 = Department.objects.get(d_id=4)
print(d1)
# <Department: Department<d_id=4,d_name=GG>>

st = Student.objects.get(s_id=6)
print(st)
#<Student: Student<s_id=6,s_name=xx>>
d1.student.add(st)

c1 = Course.objects.get(c_id=2)
st.course.add(c1)
View Code

(二).create(**kwargs)

创建一个新的对象,将它保存并放在关联的对象集中,返回新创建的对象。(一对多,多对多)。添加不存在的数据,将数据直接存入数据库。

技术分享图片
# 继续使用上面的代码

print(st)
#<Student: Student<s_id=6,s_name=xx>>

print(st.course.create(c_name=c++))
#<Course: Course<c_id=3,c_name=c++>>

print(st.course.all())
# <QuerySet [<Course: Course<c_id=3,c_name=c++>>]>
View Code

(三).remove(obj1, obj2, ...)

从关联的对象集中删除指定的模型对象。(多对多)。删除的是关系表中的数据。

技术分享图片
print(s3)
# <Student: Student<s_id=3,s_name=xiaohua>>

print(c1)
# <Course: Course<c_id=2,c_name=java>>

print(s3.course.all())
"""
<QuerySet [<Course: Course<c_id=1,c_name=python>>, <Course: Course<c_id=2,c_name=java>>, <Course: Course<c_id=3,c_name=c++>>]>
"""
s3.course.remove(c1)
View Code

(四).clear()

从关联的对象集中删除所有的对象。(多对多)

技术分享图片
s3.course.clear()
View Code

(五).直接赋值

技术分享图片
print(s2)
# <Student: Student<s_id=2,s_name=xiaohong>>

print(cs)
# <QuerySet [<Course: Course<c_id=3,c_name=c++>>]>

print(s2.course.all())
# <QuerySet []>

s2.course = cs
print(s2.course.all())
# <QuerySet [<Course: Course<c_id=3,c_name=c++>>]>
View Code

(六).注意事项

(1).add()、create()、remove()和clear()都会马上更新数据库。换句话说,在关联的任何一端,都不需要再调用save()方法。

 

七、多表查询

(一).跨关联关系的查询

Django提供了一种强大而直观的方式来“处理”查询中的关联关系,它在后台自动帮你处理好了JOIN

若要跨越关联关系,只需使用关联的模型字段的名称,并使用双下划线分隔,直至你想要的字段。这种跨越可以是任意的深度。

(1).例:

技术分享图片
# 查询学院名字为‘软件的’的学生的信息 
Student.objects.filter(department__d_name=软件)
View Code

(二).反向工作

若要引用一个“反向”的关系,只需要使用该模型的小写的名称。

(1).例:

技术分享图片
# 查询学生名字中包含‘xiao’的学生的学院信息
Department.objects.filter(student__s_name__contains=xiao)
View Code

(三).基于ManyToManyField或反向的ForeignKey来过滤一个对象时

(1).例:

技术分享图片
# 查询学号为1的学生所有的课程
Course.objects.filter(student__s_id=1)

# 查询报了课程1的所有的学生
Student.objects.filter(course__c_id=1)

# 查询报了‘python‘课程的的学生的所属学院的信息
Department.objects.filter(student__course__c_name=python)
View Code

创建博客的小案例

这个小案例只是单表的增删改查。事先先建好一个名为myblog的应用。

(一).先把模板做出来

有了实际的页面,可以根据页面来知道要实现些什么功能。

Ps:代码都是测试通过后放上来的,功能也都实现了,所以页面上的变量都不删了。

(1).创建父模板

技术分享图片
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}{% endblock %}</title>
    <link rel="stylesheet" href="{% static "css/myblog.css" %}">
</head>
<body>
<div class="nav">
    <ul>
        <li>
            <a href="{% url "myblog_index" %}" class="goto_homepage" style="margin-left: 200px;">首页</a>
        </li>
    </ul>
</div>
<br><br><br>
<div>
    {% block bodyblock %}
    {% endblock %}
</div>
</body>
</html>
View Code

(2).index页面,主页

技术分享图片
{% extends myblog/demo_base.html %}

{% block title %}
    首页
{% endblock %}

{% block bodyblock %}
    <table width="150">
        <tr>
            <td><a href="{% url "write_blog" %}" class="homepage_function_button">添加文章</a></td>
            <td><a href="{% url "blog_list" %}" class="homepage_function_button">文章列表</a></td>
        </tr>
    </table>
{% endblock %}
View Code

(3).add页面,添加一篇博客

技术分享图片
{% extends myblog/demo_base.html %}
{% block title %}
    添加博客
{% endblock %}
{% block bodyblock %}
    {% block h1_title %}
        <h1>添加新文章</h1>
    {% endblock %}
    <br>
    <form action="" method="POST"> {% csrf_token %}
        标题:<input type="text" autocomplete="off" id="title"
                  placeholder="请输入标题" name="title" value="{% block blog_title %}{% endblock %}">
        <br><br>
        内容:<textarea name="content" id="content" placeholder="请输入内容"
                     cols="30" rows="10">{% block blog_content %}{% endblock %}</textarea>
        <br><br>
        <button type="submit">发布博客</button>
    </form>
{% endblock %}
View Code

(4).update页面,修改一篇博客

修改页面与添加页面很像,所以直接继承add.html

技术分享图片
{% extends "myblog/demo_add.html" %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}修改博客{% endblock %}</title>
</head>
<body>
{% block h1_title %}
    <h1>修改文章</h1>
{% endblock %}
{% block blog_title %}{{ rs.blog_tilt }}{% endblock %}
{% block blog_content %}{{ rs.blog_content }}{% endblock %}
</body>
</html>
View Code

(5).detail页面,显示一篇博客的详情

技术分享图片
{% extends myblog/demo_base.html %}
{% block title %}
    文章详情
{% endblock %}
{% block bodyblock %}
    <h1>文章详情</h1>
    <br>
    标题:{{ rs.blog_tilt }}
    <br>
    博客内容:{{ rs.blog_content }}
{% endblock %}
View Code

(6).list页面,列出所有的博客

不仅有所有博客的列表,还拥有功能键。

技术分享图片
{% extends myblog/demo_base.html %}
{% block title %}
    文章列表
{% endblock %}
{% block bodyblock %}
    <h1 style="margin-left: 100px">文章列表</h1>
    <br>
    <table width="500px">
        <thead style="font-size:20px">
        <tr>
            <th>标题</th>
            <th>操作</th>
        </tr>
        </thead>
        <tbody>
        {% for each in rs %}
            <tr class="lightstick">
                <th><a href="{% url "blog_detail" each.id %}">{{ each.blog_tilt }}</a><br></th>
                <th><a href="{% url "update_blog" each.id %}">编辑</a> | <a
                        href="javascript:void(0);" onclick="delete_confirm(‘{% url "delete_blog" each.id %}‘);">删除</a>
                </th>
            </tr>
        {% endfor %}
        </tbody>
        {# 看着下面的表格的格式写循环 #}
        {#        <tbody>#}
        {#        <tr>#}
        {#            <th><a href="">文章1</a></th>#}
        {#            <th><a href="">编辑</a> | <a href="">删除 </a></th>#}
        {#        </tr>#}
        {#        <tr>#}
        {#            <th><a href="">文章2</a></th>#}
        {#            <th><a href="">编辑</a> | <a href="">删除 </a></th>#}
        {#        </tr>#}
        {#        </tbody>#}
    </table>
    <script>
        function delete_confirm(url) {
            if (confirm("确定要删除吗?")) {
                window.location = url;
            }
        }
    </script>
{% endblock %}
View Code

(二).写CSS(可选步骤)

只是为了稍微好看一点点,此步骤可省略。

技术分享图片
/*此CSS文件是myblog的样式*/

* {
    margin: 0;
    padding: 0;
}

/*导航栏 START*/
.nav {
    width: 100%;
    height: 50px;
    position: absolute;
    background: ghostwhite;
    border: none;
    border-bottom: lightblue 1px solid;
}

.nav ul li {
    list-style: none;
}

/*导航栏 END*/

/*导航栏 首页 链接,用于返回首页 START*/
.goto_homepage {
    display: block;
    width: 50px;
    height: 50px;
    line-height: 50px;
    text-decoration: none;
    text-align: center;
    transition: all 300ms;
}

.goto_homepage:hover {
    text-decoration: none;
    background: rgb(180, 9, 28);
    color: white;
    box-shadow: 4px 4px 5px lightgrey;
    transition: all 300ms;
}

/*导航栏 首页 链接,用于返回首页 END*/

/*首页 添加文章、文章列表 按钮样式 START*/
.homepage_function_button {
    display: block;
    width: 80px;
    height: 30px;
    line-height: 30px;
    text-align: center;
    font-family: "微软雅黑";
    font-size: 16px;
    transition: all 300ms;
}

.homepage_function_button:hover {
    text-decoration: none;
    background: rgb(180, 9, 28);
    color: white;
    box-shadow: 2px 2px 5px lightgrey;
}

/*首页 添加文章、文章列表 按钮样式 END*/

/*博客列表的光棒效果*/
.lightstick:hover {
    background: rgba(211, 211, 211, 0.25);
}

/* 通用的a标签的伪类 START */
a {
    text-decoration: none;
    transition: color 200ms;
    color: black;
}

a :link {
    color: black;
}

a:visited {
    color: black;
}

a:hover {
    text-decoration: underline;
    color: rgb(180, 9, 28);
}

a:active {
    color: black;
}

/* 通用的a标签的伪类 END */
View Code

(三).设计模型

技术分享图片
# myblog/models.py

from django.db import models


# Create your models here.

class SimpleBlog(models.Model):
    blog_tilt = models.CharField(max_length=100)
    blog_content = models.TextField()
    create_time = models.DateTimeField(auto_now_add=True)
    update_time = models.DateTimeField(auto_now=True)
View Code

注意:别忘了去Linux上makemigrations和mirgate

(四).编写视图函数

技术分享图片
from django.shortcuts import render, HttpResponse, redirect, reverse
from .models import *


# Create your views here.

# --------------- app:myblog 的逻辑 START ---------------


def index(request):
    """
    myblog的首页 : "myblog/demo_index.html"
    :param request:
    :return: 显示首页 -> myblog/demo_index.html
    """

    return render(
        request,
        "myblog/demo_index.html",
    )


def write_blog(request):
    """
    写博客的页面 : "myblog/demo_add.html"
    :param request:
    :return: 显示写博客的页面 -> myblog/demo_add.html
    """

    if request.method == "GET":
        return render(request, "myblog/demo_add.html")
    elif request.method == "POST":
        # 获取到前端form中的内容
        tile = request.POST.get("title")
        content = request.POST.get("content")

        # 放入数据库
        try:
            SimpleBlog.objects.create(blog_tilt=tile, blog_content=content)
            return HttpResponse("提交成功")
        except Exception as e:
            return HttpResponse("创建博客时,发生错误:{}".format(e))
    else:
        return HttpResponse("无效的请求!")


def get_all_blog_list(request):
    """
    列出所有的博客 : "myblog/demo_list.html"
    左侧是博客标题。
    右边是编辑、删除等功能键。
    :param request:
    :return: 显示所有博客到页面 -> myblog/demo_list.html
    """

    rs = SimpleBlog.objects.all().values()

    return render(
        request,
        "myblog/demo_list.html",
        context={
            "rs": rs,
        },
    )


def get_one_blog_detail(request, b_id):
    """
    查看一篇博客 : "myblog/demo_detail.html"
    :param request:
    :param b_id: 点详细信息时,传过来的博客id
                为了避免与id可能会发生二义性,故命名b_id
    :return: 查看某篇博客的内容 -> myblog/demo_detail.html
    """

    rs = SimpleBlog.objects.get(id=int(b_id))

    return render(
        request,
        "myblog/demo_detail.html",
        context={
            "rs": rs,
        },
    )


def update_one_blog(request, b_id):
    """
    修改一篇博客
    :param request:
    :param b_id:
    :return:
    """

    rs = SimpleBlog.objects.get(id=b_id)
    if request.method == "GET":
        return render(
            request,
            "myblog/demo_update.html",
            context={
                "rs": rs,
            },
        )
    elif request.method == "POST":
        title = request.POST.get("title")
        content = request.POST.get("content")

        try:
            rs.blog_tilt = title
            rs.blog_content = content
            rs.save()  # 为了有update_time,才使用了这种方式
        except Exception as e:
            return HttpResponse("修改时发生错误:" + e)
        else:
            return HttpResponse("修改成功!")
    else:
        return HttpResponse("修改成功!")


def delete_one_blog(request, b_id):
    """
    删除一篇博客
    :param request:
    :param b_id:
    :return:
    """

    try:
        SimpleBlog.objects.get(id=b_id).delete()
    except:
        return HttpResponse("没有此篇博客")
    else:
        return redirect(reverse("blog_list"))  # 直接重定向到列表页面


# --------------- app:myblog 的逻辑 END ---------------
View Code

(五).注册urls

技术分享图片
# myblog/views.py

from django.conf.urls import url
from myblog import views

urlpatterns = [
    url(r"^$", views.index, name="myblog_index"),  # 博客的首页
    url(r"^write_blog/$", views.write_blog, name="write_blog"),  # 写博客
    url(r"^blog_list/$", views.get_all_blog_list, name="blog_list"),  # 博客列表
    url(r"^blog_detail/(?P<b_id>d+)/$", views.get_one_blog_detail, name="blog_detail"),  # 某篇博客的详情
    url(r"^delete_blog/(?P<b_id>d+)", views.delete_one_blog, name="delete_blog"),  # 删除一篇博客
    url(r"^update_blog/(?P<b_id>d+)", views.update_one_blog, name="update_blog"),  # 更新一遍博客
]
View Code

 

以上是关于Django - 模型的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Django Summernote 中显示编程片段的代码块?

Django管理图标和图像

django.core.exceptions.ImproperlyConfigured: Requested setting DEFAULT_INDEX_TABLESPACE的解决办法(转)(代码片段

django.core.exceptions.ImproperlyConfigured: Requested setting DEFAULT_INDEX_TABLESPACE的解决办法(转)(代码片段

(Django)气流中的 ORM - 有可能吗?

AJAX相关JS代码片段和部分浏览器模型