zoukankan      html  css  js  c++  java
  • 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.60.128',
            'PORT': '3306',  # 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

    三、数据的增删改查

    (一).增

    # blog/views.py
    from .models import User
    def add_user(request):
        # 方法一:
        # tizi = User(name='tizi',age=18)
        # tizi.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

    (二).删

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

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

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

    (三).改

    # 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='changsha')
        return HttpResponse('更新数据成功!!!')
    View Code

    (四).查

    # 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='CC')
        # 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=CC>>
    
    # 还可以通过外键属性获取和设置
    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=AA>>
    
    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
  • 相关阅读:
    asp.net HC框架
    Jenkins之构建触发器配置(转载)
    Mac系统
    Macaca命令行
    Appnium学习日记四(Calculator示例)
    Appnium学习日记三(安装Android模拟器)
    Appnium学习日记二(安装Android开发环境)
    Appnium学习日记一(下载安装Appnium)
    Jmeter的安装
    WCF返回JSON的详细配置
  • 原文地址:https://www.cnblogs.com/quanquan616/p/9103562.html
Copyright © 2011-2022 走看看