Model

详解Django REST framework框架

model教程之查询高级用法

Django详解之models操作

django-model操作数据库

Django model 数据类型清单

Writing custom model fields

file upload

curtom model field

from django.db import models

class TestModel(models.Model):
    # 如果加在list_display中,那么就相当于将_unicode_改成了datetime
    list_display = ['created_at']
    # datetime为只读
    readonly_fields = ('created_at',)
    # 显示的列
    fields = ('create_at', 'id','title', 'content')
    
    username = models.CharField(max_length=32, null=False, blank=False,default='')
    title = models.CharField(max_length=80, default='')
    content = models.TextField(null=True)
    created_at = models.DateTimeField(auto_now_add=True)  #创建时改变,以后不变
    updated_at = models.DateTimeField(auto_now=True)      #每次修改时改变
    
    class Meta:
        app_label = 'TestAPP'
        db_table = 'article'
        ordering = ['-id']
        verbose_name = '文章'
        verbose_name_plural = verbose_name
        
    def __str__(self):
        return self.title
    

综合查询

article_list = Article.objects.filter(type='a', status='p')

from django.db.models import Q
users = User.objects.filter(Q(first_name__contains=query) | Q(last_name__contains=query)
        
    queryset = Snippet.objects.all()
    title = request.query_params.get('title', None)
    language = request.query_params.get('language', None)
    style = request.query_params.get('style', None)
 
    aQ = Q()
    if title is not None:
        aQ.add(Q(title__startswith=title), Q.AND)
    if language is not None:
        aQ.add(Q(language=language), Q.AND)
    if style is not None:
        aQ.add(Q(style=style), Q.AND)
 
    queryset = queryset.filter(aQ).order_by("-id")
 
    return queryset
    
过滤条件
user = User.objects.distinct('id').first()
q1 = Entry.objects.filter(headline__startswith="What")
q2 = q1.exclude(pub_date__gte=datetime.date.today())
q3 = q1.filter(pub_date__gte=datetime.date.today())
 q = q.filter(pub_date__lte=datetime.date.today())
 q = q.exclude(body_text__icontains="food")

基本操作

创建数据(两种方式):
user = User({'user': 'abc', 'email': 'abc@163.com'})
user.save()

Usr.objects.create({'user': 'abc', 'email': 'abc@163.com'})

data = {'user': 'abc', 'email': 'abc@163.com'}
User.objects.create(**data)

单表查询
res = User.objects.all()
print(res.query)            #返回sql语句

res = User.objects.get(id=1)
res = User.objects.filter(name='admin').first()
res = User.objects.filter(name='admin')

查询单个字段(values返回的是dict, values_list返回数值元组)
res = User.objects.all().values('id','title')
res = User.objects.all().values_list('id','title')

修改
User.objects.filter(name='admin').update(email='root@163.com')
或
res = User.objects.get(id=1)
res.email = 'root@163.com'
res.save()

删除
User.objects.filter(name='admin').delete()

连表操作

一对多:models.ForeignKey(其他表)
多对多:models.ManyToManyField(其他表)
一对一:models.OneToOneField(其他表)

多对多建表
class Host(models.Model):
    hid = models.AutoField(primary_key=True)
    hostname = models.CharField(max_length=32)
    ip = models.CharField(max_length=32)
 
class Group(models.Model):
    gid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=16)
 
    h2g = models.ManyToManyField('Host', through='HostToGroup')
 
class HostToGroup(models.Model):
    hgid = models.AutoField(primary_key=True)
    host_id = models.ForeignKey('Host')
    group_id = models.ForeignKey('Group')
    status = models.IntegerField()
    

增加数据:
models.Host.objects.create(hostname='c1', ip='1.1.1.1')
models.Host.objects.create(hostname='c2', ip='1.1.1.2')
models.Host.objects.create(hostname='c3', ip='1.1.1.3')
models.Host.objects.create(hostname='c4', ip='1.1.1.4')

models.Group.objects.create(name='技术部')
models.Group.objects.create(name='财务部')
models.Group.objects.create(name='人事部')

#给财务部添加一台主机:
obj = models.Group.objects.get(gid=2)
h1 = models.Host.objects.get(hid=1)
obj.h2g.add(h1)

# 把剩下的全部添加
obj = models.Group.objects.get(gid=2)
q = models.Host.objects.filter(hid__gt=1)
obj.h2g.add(*q)

#将一台机器分配给多个组(反向操作):
h = models.Host.objects.get(hid=1)
h.group_set.add(*models.Group.objects.filter(gid__gt=2))

手动创建关系:
models.HostToGroup.objects.create(status=1, group_id_id=2, host_id_id=3)

matplotlib 图片保存到 BinaryField

class Blob(models.Model):
    blob = models.BinaryField(blank = True,null = True,default = None)

import io 
import numpy as np
import matplotlib.pyplot as plt 
import Blob 
 
t = np.arange(0.0,gui_val_in,gui_val_in / 200)
s = np.sin(2 * np.pi * t)
plt.figure(figsize =(7, 6),dpi = 300,facecolor ='w')
plt.plot(t,s)
plt.xlabel('time(n)')
plt.ylabel('temp (c)')
plt.title('示例matplotlib图')
plt.grid(真)
 
#将其保存为BytesIO类型然后使用BytesIO.getvalue ()
f = io.BytesIO()#StringIO如果Python< 3 
plt.savefig(f)
b = Blob(blob = f.getvalue())
b.save()
#生成迁移文件:
python manage.py makemigrations TestModel

#执行迁移:
python manage.py migrate TestModel

自定义:
class Meta:  
    db_table = 'info'  
    verbose_name = '信息统计'  
    verbose_name_plural = '信息统计' 
        
关系:
1 一对多关系
 models.ForignKey() 外键约束
 定义在多类中
2 多对多关系
  models.ManyToManyField()
  定义在哪一个都行
3 一对一关系
  models.OntoOneField()
  定义在哪一个类都可以
 

选项
通过选项实现对字段的约束,选项如下:

null:       如果为True,表示允许为空,默认值是False。
blank:      如果为True,则该字段允许为空白,默认值是False。
db_column:  字段的名称,如果未指定,则使用属性的名称。
db_index:   若值为True, 则在表中会为此字段创建索引,默认值是False。
default:    默认值。
primary_key:若为True,则该字段会成为模型的主键字段,默认值是False,一般作为AutoField的选项使用。
unique:     如果为True, 这个字段在表中必须有唯一值,默认值是False。

Multiple databases

直接访问SQL语句

原生SQL

访问多数据库
from django.db import connections

cursor = connections['ora1'].cursor()
cursor.execute(sql)
result = cursor.fetchall()

cursor = connections['djbaseDB'].cursor()
cursor.execute('select id,username from djbase_users')
user = cursor.fetchone()
    
User.objects.using('djbaseDB').all() 
first_person = Person.objects.raw('SELECT * FROM myapp_person')[0]

people = Person.objects.raw('SELECT *, age(birth_date) AS age FROM myapp_person')
for p in people:
    print("%s is %s." % (p.first_name, p.age))

lname = 'Doe'
Person.objects.raw('SELECT * FROM myapp_person WHERE last_name = %s', [lname])

cursor.execute("SELECT id, parent_id FROM test LIMIT 2");
dictfetchall(cursor)
[{'parent_id': None, 'id': 54360982}, {'parent_id': None, 'id': 54360880}]

from django.db import connection
def my_custom_sql(self):
    with connection.cursor() as cursor:
        cursor.execute("UPDATE bar SET foo = 1 WHERE baz = %s", [self.baz])
        cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
        row = cursor.fetchone()

    return row
    

c = connection.cursor()
try:
    c.execute(...)
finally:
    c.close()

CREATE PROCEDURE "TEST_PROCEDURE"(v_i INTEGER, v_text NVARCHAR2(10)) AS
    p_i INTEGER;
    p_text NVARCHAR2(10);
BEGIN
    p_i := v_i;
    p_text := v_text;
    ...
END;

with connection.cursor() as cursor:
    cursor.callproc('test_procedure', [1, 'test'])

Django 使用多个数据库

多数据库设置

#settings.py
DATABASE_APPS_MAPPING = {
    "TestModel": "default",
    "djbase": "djbaseDB",
} 
DATABASE_ROUTERS = ['djtest.database_router.DatabaseAppsRouter']

#增加文件database_router.py

#models.py
class Users(models.Model):
    username = models.CharField(max_length=100)
    password = models.CharField(max_length=50)
 
    def __str__(self):
        return "djbase %s" % self.username
 
    class Meta:
        app_label = "djbase"
        db_table = 'user'

python manage.py makemigrations djbase
python manage.py migrate djbase
python manage.py migrate --database=djbaseDB