视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
Django中的模型与数据库(Modelsanddatabase)
2020-11-09 08:06:36 责编:小采
文档

对于数据库大家都不陌生,但是Models该怎么理解,官方文档中有这么一句话:
A model is the single, definitive source of data about your data. It contains the essential fields and behaviors of thedata you’re storing. Generally, each model maps to a single database table.

下文暂且称Models为“模型”(个人叫法)


那么,模型具备以下三个特征:

每一个模型都是一个python子类。继承django.db.models.Model模型的每一个属性代表一个数据库字段除了上述之外,jango还提供了自动生成数据库访问的API为了方便理解我们举个例子下面这个例子我们建立了一个Person的模型,且有两个字段)first_name,last_name

from django.db import models
class Person(models.Model):
 first_name = models.CharField(max_length=30)
 last_name = models.CharField(max_length=30)

first_name和last_name是Person模型的Field,每一个Field都是一个指定的类的属性,每一个属性映射到数据库的没一列

这里我就有一个疑问,到底Field能不能称为字段?


上面的Person模型将会对应一张这样的数据库表:

CREATE TABLE myapp_person (
 "id" serial NOT NULL PRIMARY KEY,
 "first_name" varchar(30) NOT NULL,
 "last_name" varchar(30) NOT NULL
);

下面我们聊聊使用,一旦你声明了一个models,你需要去告诉jango你将会去使用该models,在你的settings里把你的

应用名加到INSTALLED_APPS中

INSTALLED_APPS = (
#...
’myapp’,
#...
)
当你在INSTALLED_APPS添加新应用后,需要执行manage.py migrate 

接下来我们再来说说Fields

它是模型的重要的一部分,它定义了数据库表的字段

from django.db import models
class Musician(models.Model):
 first_name = models.CharField(max_length=50)
 last_name = models.CharField(max_length=50)
 instrument = models.CharField(max_length=100)
 class Album(models.Model):
 artist = models.ForeignKey(Musician)
 name = models.CharField(max_length=100)
 release_date = models.DateField()
 num_stars = models.IntegerField()

模型中每一个field是一个Field类实例,jango通过Field类类型去确定一下几个点。
1.数据库字段的类型
2.使用默认的HTML部件但渲染表单的field时(e.g. ,

举个例子


YEAR_IN_SCHOOL_CHOICES = (
(’FR’, ’Freshman’),
(’SO’, ’Sophomore’),
(’JR’, ’Junior’),
(’SR’, ’Senior’),
(’GR’, ’Graduate’),
)

from django.db import models
class Person(models.Model):
 SHIRT_SIZES = ( 
 (’S’, ’Small’),
 (’M’, ’Medium’),
 (’L’, ’Large’),
 )
 name = models.CharField(max_length=60)
 shirt_size = models.CharField(max_length=1,choices=SHIRT_SIZES)



>>> p = Person(name="Fred Flintstone", shirt_size="L")
>>> p.save()
>>> p.shirt_size
u’L’
>>> p.get_shirt_size_display()
u’Large’

save()
这个在后台执行了一个插入sql。但是并没有真正的导数据库知道用户执行了save(),save()没有返回值,但是save()支持参数

Model.save ([force_insert=False, force_update=False, using=DEFAULT_DB_ALIAS, update_fields=None
] )

当你执行save()操作,jango执行以下步鄹

  • 1:触发pre-save事件,这个信号,任何一个函数都可以监听这个事件

  • 2:一些有特殊的字段类型的字段做处理,例如dateField和auto_now=True这时候得到的值是jango生成的时间,这里要注意的是,数据库的时间可能跟服务器的不一样,所以这里要注意时间同步。

  • 3:为插入准备数据,每一个字段提供一个处理后的值

  • 4:为插入准备sql,这里我理解为拼sql

  • 5:发给数据库执行sql

  • all()

    all_entries = Entry.objects.all() 查看所有的内容
    
    filter(**kwargs)
    
    我们现在看下通过过滤器(filters)获取具体的值
    
    Entry.objects.filter(pub_date__year=2006)
    
    exclude(**kwargs)
    
    Entry.objects.filter(
    ... headline__startswith=’What’
    ... ).exclude(
    ... pub_date__gte=datetime.date.today()
    ... ).filter(
    ... pub_date__gte=datetime(2005, 1, 30)
    … )
    
    返回除去与查找条件相符的数据
    
    get()
    
    如果想要返回指定的一个数据
    
    one_enty = Entry.objects.get(pk=1)
    

    字段查询

    __id

    被指定的查询字段名字必须是模型field名字相对应,除非外键的情况
    
    Entry.objects.filter(blog_id=4)
    
    这时候返回并不是Entry中id=4的数据行,而是id对应主键算在的数据行

    __exact

    最普通的情况(默认添加)
    
    Entry.objects.get(headline__exact="Man bites dog")
    
    翻译成sql就为
    
    SELECT ... WHERE headline = ’Man bites dog’;
    
    
    Blog.objects.get(id__exact=14) # 明确的形式
    Blog.objects.get(id=14) # __exact 默认添加

    __iexact

    Blog.objects.get(name__iexact="beatles blog")
    
    结果可能是 "Beatles Blog", "beatles blog", or "BeAtlES blOG".
    
    不区分大小写

    __contains

    Entry.objects.get(headline__contains=’Lennon’)
    
    模糊搜索,翻译成sql
    
    SELECT ... WHERE headline LIKE ’%Lennon%’;

    __ icontains

    Entry.objects.get(headline__icontains=’Lennon’)
    
    sql:
    
    SELECT ... WHERE headline ILIKE ’%Lennon%’;

    __in

    Entry.objects.filter(id__in=[1,3,4]
    sql:
    SELECT … WHERE id IN (1,3,4);
    
    这种也可以用复合sql的形式表示
     inner_qs = Blog.objects.filter(name__contains=’Cheddar’)
    
    entries = Entry.objects.filter(blog__in=inner_qs)
    
    sql:
    
    SELECT ... WHERE blog.id IN (SELECT id FROM ... WHERE NAME LIKE ’%Cheddar%’)

    __gt 大于

    Entry.objects.filter(id__gt=4)
    sql:
    SELECT … WHERE id > 4
    __gte 大于等于
    __lt 小于
    __lte 小于等于

    __range

    import datetime
    start_date = datetime.date(2005, 1, 1)
    end_date = datetime.date(2005, 3, 31)
    Entry.objects.filter(pub_date__range=(start_date, end_date))
    
    sql:
    SELECT ... WHERE pub_date BETWEEN ’2005-01-01’ and ’2005-03-31’;

    __year

    Entry.objects.filter(pub_date_year=2005)
    sql:
    SELECT … WHERE pub_date BETWEEN ‘2005-01-01’ and ‘2005-12-31’;

    __month

    __day

    __hour

    __minute

    Entry.objects.filter(pub_date__month=12)
    sql:
    
    SELECT ... WHERE EXTRACT(’month’ FROM pub_date) = ’12’;

    __isnull

    Entry.objects.filter(pub_date__isnull=True)
    sql:
    SELECT ... WHERE pub_date IS NULL;

    下载本文
    显示全文
    专题