Django模型层之单表操作

MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库。ORM是“对象-关系-映射”的简称。

sql中的表
# 创建表
      create TABLE employee(
                  id INT PRIMARY KEY auto_increment,
                  name varchar(20),
                  gender BIT default 1,
                  birthday DATA,
                  department VARCHAR(20),
                  salary DECIMAL(8,2) unsigned,)
                );
# 添加一条表记录:
      INSERT employee(name, gender, birthday, salary, department)
             VALUES  ('alex', '1', '1985-12-12', 8000, '保洁部');
# 查询一条表记录:
        SELECT * FROM employee WHERE age=24;
# 更新一条表记录:
        UPDATE employee SET birthday='1989-10-24' WHERE id=1;
# 删除一条表记录:
        DELETE FROM employee WHERE name='alex'
而对应的Python的类对象
class Employee(models.Model):
      id=models.AutoField(primary_key=True)
      name=models.CharField(max_length=32)
      gender=models.BooleanField()
      birthday=models.DateField()
      department=models.CharField(max_length=32)
      salary=models.DecimalField(max_digits=8,decimal_places=2)
#添加一条表记录:
      emp=Employee(name='alex', gender=True, birthday='1985-12-12',epartment='保洁部')
      emp.save()
# 查询一条表记录
      Employee.objects.filter(age=24)
# 更新一条表记录
      Emplyoee.objects.filter(id=1).update(birthday='1989-10-24')
# 删除一条表记录
      Emplypee.objects.filter(name='alex').delete()

1.生成表模型

在该应用的models.py中创建模型:

from django.db import models
# Create your models here.


class Book(models.Model):
    id = models.AutoField(primary_key=True)
    title = models.CharField(max_length=32, unique=True)
    pub_date = models.DateField()
    price = models.DecimalField(max_digits=8, decimal_places=2)  # max number = 999999.99
    publish = models.CharField(max_length=32)

将模型转为mysql数据库中的表,需要在settings中配置:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME':'bms',           # 要连接的数据库,连接前需要创建好
          'USER':'root',        # 连接数据库的用户名
          'PASSWORD':'',        # 连接数据库的密码
          'HOST':'127.0.0.1',       # 连接主机,默认本级
          'PORT':3306            #  端口 默认3306
    }
}

然后我们需要找到总项目包下的__init__.py文件,写入

import pymysql
pymysql.install_as_MySQLdb()

最后通过两条数据库迁移命令即可在指定的数据库中创建表 :

>>> python manage.py makemigrations
>>> python manage.py migrate

注意:

确保配置文件中的INSTALLED_APPS中写入我们创建的app名称

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    "book"  
]   # book是应用名

如果你的Django版本是1.0而且Python版本高于3.4,可能会报错如下:

django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.3 or newer is required; you have 0.7.11.None

需要修改:

通过查找路径C:\Programs\Python\Python36-32\Lib\site-packages\Django-2.0-py3.6.egg\django\db\backends\mysql\base.py 这个路径里的文件把下面两行代码注释掉就ok了。(这个路径并不是固定的,只要找到Python\django里的mysql文件)

if version < (1, 3, 3):
     raise ImproperlyConfigured("mysqlclient 1.3.3 or newer is required; you have %s" % Database.__version__)

如果你还想要在屏幕上打印转换过程中的sql,需要在settings中进行如下配置:

扫描二维码关注公众号,回复: 4210548 查看本文章
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console':{
            'level':'DEBUG',
            'class':'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'propagate': True,
            'level':'DEBUG',
        },
    }
}

2.增删改查

添加表记录

方法1:

# create方法的返回值book_obj就是插入book表中的python葵花宝典这本书籍纪录对象
  book_obj=Book.objects.create(title="python葵花宝典",state=True,price=100,publish="苹果出版社",pub_date="2012-12-12")

方法2:

book_obj=Book(title="python葵花宝典",state=True,price=100,publish="苹果出版社",pub_date="2012-12-12")
book_obj.save()

例:views.py

from django.shortcuts import render,HttpResponse

# Create your views here.
from app01.models import Book


def index(request):

    book_obj = Book.objects.create(title="Python葵花宝典", state=True, pub_date="2012-12-12", price=100, publish='人民出版社')
    book_obj.save()
    
    book_obj_2 = Book(title="Python一阳指", state=True, pub_date='2012-12-12', price=100, publish='人民出版社')
    book_obj_2.save()

    return HttpResponse("OK!")

urls.py

from django.contrib import admin
from django.urls import path

from app01 import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path('index/', views.index),
]

用浏览器登录首页后,再查询结果:

+----+--------------------+-------+------------+--------+-----------------+
| id | title              | state | pub_date   | price  | publish         |
+----+--------------------+-------+------------+--------+-----------------+
|  1 | Python葵花宝典       |     1 | 2012-12-12 | 100.00 | 人民出版社         |
|  2 | Python一阳指         |     1 | 2012-12-12 | 100.00 | 人民出版社         |
+----+--------------------+-------+------------+--------+-----------------+

查询表记录

查询API

<1> all():                  查询所有结果,返回的是一个queryset对象

<2> filter(**kwargs):       它包含了与所给筛选条件相匹配的对象

<3> get(**kwargs):          返回与所给筛选条件相匹配的对象,返回结果有且只有一个,
                            如果符合筛选条件的对象超过一个或者没有都会抛出错误。

<4> exclude(**kwargs):      它包含了与所给筛选条件不匹配的对象

<5> order_by(*field):       对查询结果排序

<6> reverse():              对查询结果反向排序

<8> count():                返回数据库中匹配查询(QuerySet)的对象数量。

<9> first():                返回第一条记录

<10> last():                返回最后一条记录

<11> exists():              如果QuerySet包含数据,就返回True,否则返回False

<12> values(*field):        返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列
                            model的实例化对象,而是一个可迭代的字典序列
<13> values_list(*field):   它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列

<14> distinct():            从返回结果中剔除重复纪录

在models.py的Book类中加上这两行,让屏幕打印出具体的书名:

def __str__(self):
    return self.title

例:views.py(注意可能需要重启下django)

from django.shortcuts import render,HttpResponse

# Create your views here.
from app01.models import Book


def index(request):

    # book_obj = Book.objects.create(title="Python葵花宝典", state=True, pub_date="2012-12-12", price=100, publish='人民出版社')
    # book_obj.save()

    # book_obj_2 = Book(title="Python一阳指", state=True, pub_date='2012-12-12', price=100, publish='人民出版社')
    # book_obj_2.save()

    book_list = Book.objects.all()
    # print(book_list)  # [obj1, obj2,...]

    for obj in book_list:
        print(obj.title, obj.price)

    return HttpResponse("OK!!!")

屏幕打印:

Python葵花宝典 100.00
Python一阳指 100.00

再加一本书:

     book_obj_2 = Book(title="Python降龙十八掌", state=True, pub_date='2015-12-12', price=200, publish='路飞出版社')
     book_obj_2.save()

其他的查询API示例:(注意只要查询结果是<QuerySet>类型的都可以继续用相应方法调用,分清调用者和返回值)

from django.shortcuts import render,HttpResponse

# Create your views here.
from app01.models import Book


def index(request):

    book_first_1 = Book.objects.all().first()  # 调用者:queryset对象,返回值:model
    print("book_first:", book_first_1)
    book_first_2 = Book.objects.all()[2]
    print("book_first:", book_first_2)
    book_filter = Book.objects.filter(title="Python葵花宝典", price=100)   # [obj1, obj2,...]
    print("book_filter:", book_filter)
    book_filter_first = Book.objects.filter(price=100).first()
    print("book_filter_first:", book_filter_first)
    book_get = Book.objects.get(price=200)   # 有且只有一条结果,否则会报错
    print("book_get.pub_date:", book_get.pub_date)
    book_exclude = Book.objects.exclude(price=200, title="Python降龙十八掌")
    print("book_get.pub_date:", book_exclude)
    book_order_by = Book.objects.order_by("price")  # "-price"表示逆序
    book_order_by_1 = Book.objects.order_by("price", "-id")  # 当price相等时再用id排序
    print("book_order_by:", book_order_by, "book_order_by_1:", book_order_by_1)
    book_exists = Book.objects.all().exists()
    print("book_exists", book_exists)
    book_values = Book.objects.all().values("title")
    print("book_values", book_values)
    book_values_list = Book.objects.all().values_list("price", "title")
    print("book_values_list", book_values_list)
    book_distinct = Book.objects.all().values("price").distinct()
    print("book_distinct:", book_distinct)

    return HttpResponse("OK!!!")

对应的结果:

book_first: Python葵花宝典
book_first: Python降龙十八掌
book_filter: <QuerySet [<Book: Python葵花宝典>]>
book_filter_first: Python葵花宝典
book_get.pub_date: 2015-12-12
book_get.pub_date: <QuerySet [<Book: Python葵花宝典>, <Book: Python一阳指>]>
book_order_by: <QuerySet [<Book: Python葵花宝典>, <Book: Python一阳指>, <Book: Python降龙十八掌>]> book_order_by_1: <QuerySet [<Book: Python一阳指>, <Book: Python葵花宝典>, <Book: Python降龙十八掌>]>
book_exists True
book_values <QuerySet [{'title': 'Python葵花宝典'}, {'title': 'Python一阳指'}, {'title': 'Python降龙十八掌'}]>
book_values_list <QuerySet [(Decimal('100.00'), 'Python葵花宝典'), (Decimal('100.00'), 'Python一阳指'), (Decimal('200.00'), 'Python降龙十八掌')]>
book_distinct: <QuerySet [{'price': Decimal('100.00')}, {'price': Decimal('200.00')}]>

模糊查询:

Book.objects.filter(price__in=[100, 200, 300])
Book.objects.filter(price__gt=100)  # 大于100
Book.objects.filter(price__lt=100)  # 小于100
Book.objects.filter(price__range=[100, 200])
Book.objects.filter(title__contains="python")  # 包含
Book.objects.filter(title__icontains="python")  # 不管大小写
Book.objects.filter(title__startswith="py")
Book.objects.filter(pub_date__year=2012)

删除表记录

Book.objects.filter(price=200).delete()  # 删除所有price=200的书
Book.objects.filter(pub_date__year=2005).delete()  # 
Book.objects.filter(price=100).first().delete()
Book.objects.filter(title="Python一阳指").update(title="Python六脉神剑")
# update只能被model对象调用

总结:

必须分清这些api能被Queryset对象还是model对象调用。

猜你喜欢

转载自www.cnblogs.com/haoqirui/p/10013033.html