美文网首页
Django笔记:模型与数据库

Django笔记:模型与数据库

作者: 倔犟的贝壳 | 来源:发表于2021-05-29 10:53 被阅读0次

    Django对各种数据库提供了很好的支持,包括PostgreSQL,MySQL,SQLite和Oracle,而且为这些数据库提供了统一的调用API,这些API统称为ORM框架。通过使用Django内置的ORM框架可以实现数据库连接和读写操作
    本文以MySQL为例。

    1. 配置目标数据库

    在settings.py中设置数据库信息 (前提是先安装MySQL,然后创建django_db数据库)

    DATABASES = {
        'default': {
            'ENGINE':'django.db.backends.mysql',
            'NAME':'django_db', #数据库名称
            'USER':'root', #数据库的用户名
            'PASSWORD':'数据库密码',
            'PORT':'3306'
        },
    }
    

    2. 构建虚拟数据库

    在App(此文中是index)的models.py文件中以类的形式定义模型。因为Django对模型和目标数据库之间有自己的映射规则,所以只能通过模型创建。如果自己直接建表,可能不一定符合Django的建表规则,导致模型与数据库之间无法建立通信联系。

     #model.py
    class Product(models.Model):
        id = models.IntegerField(primary_key=True)
        name = models.CharField(max_length=50)
        type = models.CharField(max_length=20)
    
    • 模型以类的形式定义,并且继承Django的models.Model类。
    • 上述代码将Product类与数据表Product构成映射关系。

    3.通过模型在目标数据库中创建相应的数据表

    建表通过manage.py完成。

    • 首先,根据models.py生成相关的.py文件,该文件用于创建数据表

    python manage.py makemigrations

    makemigrations 指令将models.py的内容生成数据表的脚本代码。
    执行完上述代码,在migrations文件夹下,会生成一个xxxx_initial.py文件。

    0001_initial.py
    • 然后,使用migrate指令,根据生成脚本代码(0001_initial.py )创建数据表

    python manage.py migrate

    执行完上述语句,在数据库中会生成index_product表,对应模型Product。同时还默认创建多个数据表。除了index_product表外,其余表都是Django内置的功能生成的,主要用于Admin站点、用户认证和Session会话功能

    Operations to perform:
    Apply all migrations: admin, auth, contenttypes, index, sessions
    Running migrations:
    Applying contenttypes.0001_initial... OK
    Applying auth.0001_initial... OK
    Applying admin.0001_initial... OK
    Applying admin.0002_logentry_remove_auto_add... OK
    Applying admin.0003_logentry_add_action_flag_choices... OK
    Applying contenttypes.0002_remove_content_type_name... OK
    Applying auth.0002_alter_permission_name_max_length... OK
    Applying auth.0003_alter_user_email_max_length... OK
    Applying auth.0004_alter_user_username_opts... OK
    Applying auth.0005_alter_user_last_login_null... OK
    Applying auth.0006_require_contenttypes_0002... OK
    Applying auth.0007_alter_validators_add_error_messages... OK
    Applying auth.0008_alter_user_username_max_length... OK
    Applying auth.0009_alter_user_last_name_max_length... OK
    Applying auth.0010_alter_group_name_max_length... OK
    Applying auth.0011_update_proxy_permissions... OK
    Applying auth.0012_alter_user_first_name_max_length... OK
    Applying index.0001_initial... OK
    Applying sessions.0001_initial... OK

    用数据库可视化工具查看数据库中创建的表:

    数据库中创建的数据表.png

    4.插入数据

    为方便查看,使用shell模式,在Pycharm的Terminal下开启Shell:
    python manage.py shell

    • 方式一
    In [6]: from index.models import *
    
    In [7]: p = Product()
    
    In [8]: p.id = 8
    
    In [9]: p.name = 'nova 5'
    
    In [10]: p.type = '手机'
    
    In [11]: p.save()
    
    
    • 方式二
    In [12]: Product.objects.create(id = 9,name = 'nova 8',type = '手机')
    
    Out[12]: <Product: Product object (9)>
    
    • 方式三
    In [13]: p = Product(id = 10,name = '荣耀10',type = '手机')
    
    In [14]: p.save()
    
    前面7条数据通过可视化工具DBeaver添加的,后面3条是通过上面代码添加的

    5.更新数据

    Product.objects.filter(name='荣耀').update(name='荣耀8')
    

    先用filter设置条件,然后用update更新。上述例子将name='荣耀'的记录更新为name='荣耀8'。如果全表更新,则不需要使用filter,直接使用update。

    6.删除数据

    #删除1条数据
    In [22]: Product.objects.get(id=10).delete()
    Out[22]: (1, {'index.Product': 1})
    
    #删除多条数据
    In [24]: Product.objects.filter(name__startswith='nova').delete()
    Out[24]: (2, {'index.Product': 2})
    
    • 查询条件get:查询字段必须是主键或唯一约束的字段,并且查询数据必须存在,如果查询重复或不存在,会抛出异常。

    • 查询条件filter:查询字段没有限制,只要是数据表的某一字段即可。查询结果以列表形式返回,如果查询为空,返回空列表。

    • filter的模糊查询

    filter(要查的字段__指令= "过滤的内容")

    #指令
    __exact 精确等于 like ‘aaa’
    __iexact 精确等于 忽略大小写 ilike ‘aaa’
    __contains 包含 like ‘%aaa%’
    __icontains 包含 忽略大小写 ilike ‘%aaa%’,但是对于sqlite来说,contains的作用效果等同于icontains。
    __gt 大于
    __gte 大于等于
    __lt 小于
    __lte 小于等于
    __in 存在于一个list范围内
    __startswith 以…开头
    __istartswith 以…开头 忽略大小写
    __endswith 以…结尾
    __iendswith 以…结尾,忽略大小写
    __range 在…范围内
    __year 日期字段的年份
    __month 日期字段的月份
    __day 日期字段的日
    __isnull=True/False
    __isnull=True 与 __exact=None的区别
    ————————————————
    

    filter中的 可以用Q将 and or not 联系起来。 and操作可以不用Q

    from django.db.models import Q
    
    Product.objects.filter(Q(name='畅玩') & Q(type='手机'))
    等价于:
    Product.objects.filter(name='畅玩',type='手机')
    #or 操作
    Product.objects.filter(Q(name='畅玩') |  Q(name='荣耀8'))
    
    
    

    7.读取数据并显示

    在views.py中读取数据并将数据传入模板:

    >def index(request):
        #通过Django内置的ORM框架,查询product数据表
        type_list = Product.objects.values('type').distinct()
        name_list = Product.objects.values('name','type')
        context = {'title':'首页','type_list':type_list,'name_list':name_list}
        return render(request,'index.html',context=context,status=200)
    

    在模板index.html显示:

    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>{{title}}</title>
    </head>
    <body>
    <ul id="cate_box" class="lf">
        {% for type in type_list %}
        <li>
            <h3><a href="#">{{type.type}}</a> </h3>
            <p>
                {% for name in name_list %}
                    {% if name.type == type.type %}
                        <span>{{name.name}}</span>
                    {% endif %}
                {% endfor %}
            </p>
        </li>
        {% endfor %}
    </ul>
    </body>
    </html>
    

    运行之后显示的结果为:

    index.html效果图

    相关文章

      网友评论

          本文标题:Django笔记:模型与数据库

          本文链接:https://www.haomeiwen.com/subject/xisksltx.html