搜索
您的当前位置:首页Django中的模型与数据库(Modelsanddatabase)

Django中的模型与数据库(Modelsanddatabase)

时间:2020-11-09 来源:智榕旅游

对于数据库大家都不陌生,但是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;
    Top