A913830 发表于 2021-11-15 15:45

django 模型和ORM

Django 模型
模型是一个Python类,它是由django.db.models.Model派生出的子类
一个模型类代表数据库中的一张数据表
模型类中的每一个类属性都代表数据库中的一个字段
模型是数据交互的接口,是表示和操作数据库的方法和方式
ORM 对应关系表:https://www.runoob.com/wp-content/uploads/2020/05/orm-object.pngDjango ORMDjango 模型使用自带的 ORM。对象关系映射(Object Relational Mapping,简称 ORM )用于实现面向对象编程语言里不同类型系统的数据之间的转换。ORM 在业务逻辑层和数据库层之间充当了桥梁的作用。ORM 是通过使用描述对象和数据库之间的映射的元数据,将程序中的对象自动持久化到数据库中。https://www.runoob.com/wp-content/uploads/2020/05/django-orm1.png

A913830 发表于 2021-11-15 17:08

字段选项 field_options(null=True)
class Book(models.Model):
    title = models.CharField(max_length=30,db_index=True)
    price = models.DecimalField(decimal_places=2,max_digits=7)
    pub_date = models.DateField(default='1998-10-31')


python manage.py makemigrations
python manage.py migrate


def add_view(request):
    from . import models
    try:
      abook = models.Book.objects.create(title='java',price=22)
      return HttpResponse('CRUD success.')
    except Exception as err:
      return HttpResponse(err)

A913830 发表于 2021-11-15 17:16

本帖最后由 A913830 于 2021-11-16 09:56 编辑

模型管理器对象


class User(models.Model):
    name = models.CharField(max_length=12)
    age = models.SmallIntegerField()


    class Meta:
      db_table = "User"
当我们对模型类进行查询时使用`类名.objects.all()`获取此模型类下的所有数据
objects从何而来?


因为objects是django自动生成的管理器对象,通过这个对象可以实现对数据的查询
objects是models.manager 类的一个对象,我们可以自定义这个对象,自定义后系统就不在为我们自动生成




创建自己的管理器对象


class User(models.Model):
    name = models.CharField(max_length=12)
    age = models.SmallIntegerField()
   
    user2=models.Manager()


    class Meta:
      db_table = "User"
在models.py中进行创建:user2=models.Manager()
注意新建哪个类的管理器对象就需要在哪个类中写


此时我们再用objects进行查询就会报错
因为我们自定义对象后系统就不会自动为我们生成objects对象
但是此时可以用我们写的user2对象进行操作 User.user2.all()


继承Manager的类的重写
class MiddleWareManager(models.Manager): # 继承models.Manager
    # 重新all()方法
    def all(self):
      return super().all().filter(age__lte=19) # 调用父类的all()方法, 并过滤


class User(models.Model):
    name = models.CharField(max_length=12)
    age = models.SmallIntegerField()

    objects = MiddleWareManager() # 新建MiddleWareManager的对象

    class Meta:
      db_table = "User"

再使用User.objects.all()查询结果是过滤之后的结果


db_table用于指定自定义数据库表名
verbose_name给模型类起一个更可读的名字

A913830 发表于 2021-11-16 11:33

python manage.py createsuperuser


vim ./book/admin.py
from app01.models import Book,Author
admin.site.register(Book)
admin.site.register(Author)


class Book(models.Model):
    title = models.CharField(max_length=30,unique=True,verbose_name='book_name')
    price = models.DecimalField(decimal_places=2,max_digits=7,null=True,)
    pub = models.CharField(max_length=50,null=True,verbose_name='publish')
    market_price = models.DecimalField(max_digits=7,decimal_places=2,null=True)
    def __str__(self):
         return self.title
      
class Author(models.Model):
    name = models.CharField(max_length=30)
    age = models.IntegerField()
    email = models.EmailField()

A913830 发表于 2021-11-16 11:35

<form action="./" method="post">
    <div>title:<input type="text" name="title"></div>
    <div>publish:<input type="text" name="pub"></div>
    <div>price:<input type="text" name="price"></div>
    <div>market_price:<input type="text" name="m_price"></div>
    <div><input type="submit"></div>
</form>


from . import models
def add_view(request):
    if request.method == 'GET':
      return render(request,'bookstore/add_book.html')
    elif request.method == 'POST':
      title = request.POST.get('title')
      pub = request.POST.get('pub')
      price = request.POST.get('price')
      m_price = request.POST.get('m_price')
      try:
            models.Book.objects.create(
                title=title,pub=pub,price=price,
                market_price=m_price)
            return HttpResponse('CRUD success')
      except Exception as err:
            return HttpResponse(err)

A913830 发表于 2021-11-16 16:04

本帖最后由 A913830 于 2021-11-16 16:28 编辑

<div><a href="/add">add</a></div>
<table>
    <tr>
      <td>id</td>
      <td>title</td>
      <td>publish</td>
      <td>price</td>
      <td>market_price</td>
      <td>delect</td>
      <td>update</td>
    </tr>
    {% for abook in books %}
      <tr>
            <td>{{ abook.id }}</td>
            <td>{{ abook.title }}</td>
            <td>{{ abook.pub }}</td>
            <td>{{ abook.price}}</td>
            <td>{{ abook.market_price }}</td>
            <td><a href="/del/{{ abook.id }}">delete</a></td>
            <td><a href="/mod/{{ abook.id }}">update</a></td>
      </tr>
    {% endfor %}
</table>


def show_all(request):
    books = models.Book.objects.all()
    return render(request,'bookstore/list.html',locals())

A913830 发表于 2021-11-16 16:39

本帖最后由 A913830 于 2021-11-16 16:44 编辑

<form action="/mod/{{abook.id}}" method="post">
    <div>title:<input type="text" value="{{abook.title}}" readonly="readonly"></div>
    <div>publish:<input type="text" value="{{abook.pub}}" readonly="readonly"></div>
    <div>price:<input type="text" value="{{abook.price}}" readonly="readonly"></div>
    <div>market_price:<input type="text" name="m_price" value="{{abook.m_price}}"></div>
    <div><input type="submit"></div>
</form>


def mod_view(request,id):
    try:
       abook = models.Book.objects.get(id=id)
    except Exception as err:
      return HttpResponse(err)


    if request.method == 'GET':
      return render(request,'bookstore/mod.html',locals())
    elif request.method == 'POST':
      m_price = float(request.POST.get('m_price','0'))
      abook.market_price = m_price
      abook.save()
      from django.http import HttpResponseRedirect
      return HttpResponseRedirect('/all')



执行查询:
用get()检索单个对象 filter()总是返回一个QuerySet即便只有一个对象满足查询条件 —— 这种情况下,QuerySet 只包含了一个元素。
若你知道只会有一个对象满足查询条件,你可以在 Manager 上使用 get() 方法,它会直接返回这个对象:
>>> one_entry = Entry.objects.get(pk=1)
字段查询 查询谓词:
字段查询即你如何制定 SQL WHERE 语句。它们以关键字参数的形式传递给 QuerySet 方法 filter(), exclude() 和 get()。
基本的查询关键字参数遵照 field__lookuptype=value。(有个双下划线)。例如:
>>> Entry.objects.filter(pub_date__lte='2006-01-01')
转换为 SQL 语句大致如下:
SELECT * FROM blog_entry WHERE pub_date <= '2006-01-01';


A913830 发表于 2021-11-17 14:52

本帖最后由 A913830 于 2022-3-9 14:00 编辑

django 如何查看orm转换成的sql语句

from app01.models import Message


all_messages = Message.objects.all()
sliced_query = Message.objects.all()[:1]
print(all_messages.query)
print(sliced_query.query)    适用queryset对象
django框架采用的ORM模型,我们可以通过mysql的日志记录实时查看执行的sql语句,具体步骤如下:
第一步:进入mysql,查看日志开启的状态和log文件路径;


mysql>show variables like "%general_log%";
+------------------+------------------------------+
| Variable_name    | Value                        |
+------------------+------------------------------+
| general_log       | OFF                        |
| general_log_file | /var/lib/mysql/localhost.log |
+------------------+------------------------------+


第二步:如上操作,OFF说明没有开启日志记录,我们可以通过如下命令设置日志启动状态 or 更改日志路径和日志名;


mysql> set global general_log_file = '/var/lib/mysql/localhost.log';
mysql> set global general_log = 'ON';


mysql>show variables like "%general_log%";
+------------------+------------------------------+
| Variable_name    | Value                        |
+------------------+------------------------------+
| general_log       | ON                           |
| general_log_file | /var/lib/mysql/localhost.log |
+------------------+------------------------------+
日志开启后,所有执行的sql都会被记录下来,但是如果重启mysql就会停止记录,即general_log的值变回OFF!


mysql数据库支持两种日志存储方式:文件(file) and 数据表(table)
# 查询mysql日志存储方式
mysql> show variables like "%log_output%";
# 设置mysql日志存储方式:文件存储方式(默认方式)
set global log_output = "FILE";
# 设置mysql日志存储方式:数据表存储方式
set global log_output = "TABLE";
# 设置mysql日志存储方式:文件和数据表同时存储日志
set global log_output = "TABLE,FILE";


页: [1]
查看完整版本: django 模型和ORM