zoukankan      html  css  js  c++  java
  • django-数据库[ 基本操作 ]

    os:mac, django1.9.5,  python3.5

    database:mysql

    0.背景

    django中每一个模型model都对应于数据库中的一张表,每个模型中的字段都对应于数据库表的列。

    方便的是,django可以自动生成这些create table, alter table, drop table的操作。

    想想看,如果我们每次修改django中的数据模型,又要去同步修改数据库中的模型,是多么麻烦的一件事。更不用说那些容易发生的细节上的错误了。

    1.创建模型

    假设我们为一个shopping mall创建一个简单的数据模型:

    商场里分各个区域,如化妆品区,女装区,男装区等等。对应Area模型,有字段区域名name, 描述description, 管理人员manager。

    接着,在每个区域中又有许多商铺。对应Store模型,有字段商铺名name, 外键area(Area与Store为一对多关系)。

    而每个商铺里,贩卖各种商品。对应Item模型,有字段商品名name, 价格price, 外键store(Store与Item为一对多关系)。

     1 from django.db import models
     2 from django.contrib.auth.models import User
     3 
     4 
     5 class Area(models.Model):
     6     name = models.CharField(max_length=30)
     7     description = models.CharField(max_length=100)
     8     manager = models.ForeignKey(User, blank=True, null=True)
     9 
    10     def __str__(self):
    11         return self.name
    12 
    13 
    14 class Store(models.Model):
    15     name = models.CharField(max_length=30)
    16     area = models.ForeignKey(Area, on_delete=models.CASCADE, related_name='stores')
    17 
    18     def __str__(self):
    19         return self.name
    20 
    21 
    22 class Item(models.Model):
    23     name = models.CharField(max_length=30)
    24     price = models.IntegerField()
    25     store = models.ForeignKey(Store, on_delete=models.CASCADE)
    26 
    27     def __str__(self):
    28         return self.name

    1.1 主键

    我们注意到,在上面定义model时,我们并没有定义主键primary key。这是因为除非你显式指定,django会自动为你的模型增加一个字段名为id的主键。

    id = models.AutoField(primary_key=True)

    当然,我们也可以自定义主键,只要给字段设置primary_key=True就可以。这时候,django就不会自动为我们的模型设置id主键了。

    primary_key=True意味着null=False 以及unique=True。也就是说,主键是非空且独一无二的,它是用来在这个表中标识这一行数据的。

    在django的模型中,主键也是只读的。

    1.2 外键

    在模型中定义外键时,同步数据库后,django默认在外键字段名后加上"_id"作为数据库表的列名。

    ForeignKey()常用的额外参数如下:

    级联删除: on_delete=models.CASCADE

    反向查询: 如我们在Store模型的外键store字段中设置realted_name='stores',可以在关系的另一端,即area端反向查询到stores

    1.3 __str__()方法

    给每个模型定义__str__()方法是一个很好的做法,这不只是为了交互时方便,也是因为django会在其他一些地方用 __str__() 来显示对象。

    注意__str__()方法必须返回字符串。

    2.生成模型

    每一次对model的修改,都需要运行以下两条命令来同步我们的数据库:

    1 python manage.py makemigrations
    2 python manage.py migrate

    2.1 makemigrations

    其中第一条命令的作用是生成migrations文件。

    在我们的例子中,makemigrations后shell中会有以下输出:

    1 Migrations for 'shop':
    2   0001_initial.py:
    3     - Create model Area
    4     - Create model Store
    5     - Create model Item

    而这时候,在我们的app shop中能看到一个migrations文件夹,打开0001_initial.py,就能看到对应的migration语句。

    2.2 migrate

    而第二条命令的作用是将这些migrations应用到数据库上去。

    在我们的例子中,migrate后shell中会有以下输出:

    1 Operations to perform:
    2   Apply all migrations: silk, sessions, admin, auth, shop, contenttypes
    3 Running migrations:
    4   Rendering model states... DONE
    5   Applying shop.0001_initial... OK

    自动生成的表名为app名(shop)和模型的小写名称(area, store, item)的组合(用下划线_组合)。如在app shop下的模型Area对应数据库中的shop_area表。

    2.3 说明

    每个app的migration文件都会在app中的migrations文件夹下被生成。

    在django中,每一次对模型以及模型中的字段的增加,删除或修改,都会在执行python manage.py makemigrations后生成相应的migrations。

    建议仔细检查makemigrations后shell中的输出,尤其是在对模型进行了复杂的改变时。检查完毕后再执行migrate。

    当然,如果你在运行makemigrations后反悔了,大可以不执行migrate,而是转去删除刚刚生成的migrations文件。

    everyone deserves a second chance:)

    3.数据库的基本操作

    3.1 增

    我们先为shopping mall增加一个化妆品区:

    1 from django.shortcuts import HttpResponse
    2 from .models import Area
    3 
    4 
    5 def add_area(request):
    6     area = Area.objects.create(name='cosmetic', description='充满香味儿的区域')
    7 
    8     return HttpResponse('added!')

    其中,第六行代码 area = Area.objects.create(name='cosmetic', description='充满香味儿的区域')

    所对应的mysql语句为:

    insert into shop_area(name,description) values('cosmetic','充满香味儿的区域');

    3.2 查

    现在,我们来列出shopping mall中的所有区域:

    1 from django.shortcuts import HttpResponse
    2 from .models import Area
    3 
    4 
    5 def list_area(request):
    6     area = Area.objects.all()
    7     print(area)                    # 在shell输出[<Area: 'cosmetic'>],如果没有定义__str__(),将输出无意义的[<Area: Area object>]
    8 
    9     return HttpResponse('listed!')

    第六行代码 area = Area.objects.all()

    相当于mysql语句:

    select * from shop_area;

    复习一下:shop_area为django为模型自动生成的表名(app_model)

    3.3 改

    在3.1中,我们并没有为化妆品区指定管理人员。现在,我们修改化妆品区的信息,将rinka指定为管理人员。

    首先,我们要创建一个rinka用户。这里我将创建一个名为rinka的superuser:

    python manage.py createsuperuser

    接着,将我们创建的rinka用户指定为化妆品区的管理人员:

     1 from django.shortcuts import HttpResponse
     2 from .models import Area
     3 from django.contrib.auth.models import User
     4 
     5 
     6 def update_area(request):
     7     rinka = User.objects.get(username='rinka')
     8     area = Area.objects.get(id=1)
     9     area.manager = rinka
    10     area.save()
    11 
    12     return HttpResponse('updated!')

    注意必须调用对象的save()方法,对对象实例的修改才会保存到数据库中去。这是一个容易出错的地方。

    第8~10行代码对应的mysql语句为:

    update shop_area set manager_id=1 where id=1;

    复习一下:manager_id为django默认为外键生成的列名(foreignkey_id)

    3.4删

    删除操作很简单,我们现在来删除数据库表shop_area中id为1的那行数据:

    1 from django.shortcuts import HttpResponse
    2 from .models import Area
    3 
    4 
    5 def delete_area(request):
    6     area = Area.objects.get(id=1)
    7     area.delete()
    8 
    9     return HttpResponse('deleted!')

    第6~7行语句对应的mysql语句为:

    delete from shop_area where id=1;

    总结

    django中数据库基本操作:

    1.同步数据库

    python manage.py makemigrations  #生成migrations

    python manage.py migrate   #应用migrations

    2.增

    Model.objects.create(**kwargs)

    3.查

    Model.objects.all()

    4.改

    m = Model.objects.get(id=1)

    m.name = 'new_name'

    m.save()

    5.删

    m = Model.objects.get(id=1)

    m.delete()

  • 相关阅读:
    几款比较好用的思维导图工具
    单例模式的七种实现
    从中央仓库下载所想要的jar包
    单例模式实现的几种方式
    两个数组比较看看结果
    CSS 基础 例子 伪元素和伪类 & 区别
    CSS 基础 例子 背景色 & 背景图片
    CSS 基础 例子 水平 & 垂直对齐
    CSS 基础 例子 浮动float
    CSS 基础 例子 行高line-height
  • 原文地址:https://www.cnblogs.com/rinka/p/django_database_basic_operations.html
Copyright © 2011-2022 走看看