django model

原文地址:https://docs.djangoproject.com/en/1.11/topics/db/models/#fields

1.简介

一个model 对应于数据中的一个表(A model class represents a database table, and an instance of that class represents a particular record in the database table.)

示例:

from django.db import models

class Person(models.Model): # 定义的模型需要继承 models.Model类
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)

其中,first_name与last_name都是模型中的字段,也就是对应数据库中表的域。上述模型对应与数据库中入下表结构:

CREATE TABLE myapp_person (  #该表的名称 “myapp_person” 是自动从某些模型元数据中派生出来
    "id" serial NOT NULL PRIMARY KEY,  #一个 id 字段会被自动添加,但是这种行为可以被改写
    "first_name" varchar(30) NOT NULL,
    "last_name" varchar(30) NOT NULL
);

2.字段

2.1 字段类型

在model中的每个域都是某种Field类的实例。Django使用Filed类型来定义如下信息:

  • 在数据库中表字段的存储类型,例如:integer,varchar,text;
  • 默认的HTML widget类型,例如:<input type="text"> 或<select>
  • 校验的最低要求;

Django内置的field 完整列表:https://docs.djangoproject.com/en/1.11/ref/models/fields/#model-field-types

当然,Django 也支持自定义类型:参考:https://docs.djangoproject.com/en/1.11/howto/custom-model-fields/

2.1.1 filed 选项

每种field 都有一定的可选参数。例如对于CharFiled,可指定该字符串的最大长度。例如:

name=models.CharField(max_length=255)

可选参数包括:

  • null :是否存储空值;
  • blank: 是否允许空值;
  • choices: 定义field值的范围。如果指定该值,对form默认绑定的widget为select box;
  • default :定义默认值;
  • help_text :显示的帮助信息;
  • primary_key:
  • unique

2.1.2 自增主键字段

如果你不指定主键的化,Django 默认为每个model 增加如下字段,作为主键:

id = models.AutoField(primary_key=True)

3. 定义多表之间的关系

Django支持如下几种关系:

  • 多对一
  • 多对多
  • 一对一

下面分别说明:

3.1 多对一关系

在多的一端,增加一个ForeignKey域来参数关系。例如:

from django.db import models

class Manufacturer(models.Model):
    # ...
    pass

class Car(models.Model):
    manufacturer = models.ForeignKey(Manufacturer, on_delete=models.CASCADE)
    # ...

建议将该字段的名字定义成对应的model名的小写形式。

3.2 多对多关系

使用ManyToManyField来定义。建议将多对多关系字段名字使用对应模型名称的复数形式。将该字段放在多对多的那一端都无所谓,但是你只能将其放在一端模型中。一般来说,将该字段放在可以经常编辑的一端。例如,你可以定义你的pizza上有多上配料。

例如:

每种披萨上会有多种配料,每种配料也对应多种披萨,则可定义如下模型:

from django.db import models

class Topping(models.Model):
    # ...
    pass

class Pizza(models.Model):
    # ...
    toppings = models.ManyToManyField(Topping)

另外,在多对多关系中,如果关联关系也有特定的属性,如会员、俱乐部场景中,会员入会,在建立关系时,也需要存储入会的关系属性,如入会时间等。这时,可以通过第三个模型来描述,例如:

from django.db import models

class Person(models.Model):
    name = models.CharField(max_length=128)

    def __str__(self):              # __unicode__ on Python 2
        return self.name

class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(Person, through='Membership')

    def __str__(self):              # __unicode__ on Python 2
        return self.name

class Membership(models.Model):
    person = models.ForeignKey(Person, on_delete=models.CASCADE)
    group = models.ForeignKey(Group, on_delete=models.CASCADE)
    date_joined = models.DateField()
    invite_reason = models.CharField(max_length=64)

这时,需要通过through 字段指明关系中间表模型。

3.3 一对一关系

通过 OneToOneField字段声明字段。例如:

from django.db import models

class Place(models.Model):
    name = models.CharField(max_length=50)
    address = models.CharField(max_length=80)

    def __str__(self):              # __unicode__ on Python 2
        return "%s the place" % self.name

class Restaurant(models.Model):
    place = models.OneToOneField(
        Place,
        on_delete=models.CASCADE,
        primary_key=True,
    )
    serves_hot_dogs = models.BooleanField(default=False)
    serves_pizza = models.BooleanField(default=False)

    def __str__(self):              # __unicode__ on Python 2
        return "%s the restaurant" % self.place.name

class Waiter(models.Model):
    restaurant = models.ForeignKey(Restaurant, on_delete=models.CASCADE)
    name = models.CharField(max_length=50)

    def __str__(self):              # __unicode__ on Python 2
        return "%s the waiter at %s" % (self.name, self.restaurant)

4.model 操作

实例模型:

from django.db import models

class Blog(models.Model):
    name = models.CharField(max_length=100)
    tagline = models.TextField()

    def __str__(self):
        return self.name

class Author(models.Model):
    name = models.CharField(max_length=200)
    email = models.EmailField()

    def __str__(self):
        return self.name

class Entry(models.Model):
    blog = models.ForeignKey(Blog, on_delete=models.CASCADE)
    headline = models.CharField(max_length=255)
    body_text = models.TextField()
    pub_date = models.DateField()
    mod_date = models.DateField()
    authors = models.ManyToManyField(Author)
    n_comments = models.IntegerField()
    n_pingbacks = models.IntegerField()
    rating = models.IntegerField()

    def __str__(self):
        return self.headline

通过objects,你可以做:

1. 创建、保存对象到数据库

(执行insert 语句)

p = Person.objects.create(first_name="Bruce", last_name="Springsteen")

或是:

b = Blog(name='Beatles Blog', tagline='All the latest Beatles news.')
b.save()

2. 对数据库中的数据进行修改

(执行update语句)

b5.name = 'New name'
b5.save()

3. 对model中负责数据进行修改

对model的Foreign key类型或是 ManyToManyField字段的update操作

(1)对于Foreign key的update和普通字段是一样的操作。

>>> from blog.models import Blog, Entry
>>> entry = Entry.objects.get(pk=1)
>>> cheese_blog = Blog.objects.get(name="Cheddar Talk")
>>> entry.blog = cheese_blog
>>> entry.save()

(2)对于ManyToManyField的update:

>>> john = Author.objects.create(name="John")
>>> paul = Author.objects.create(name="Paul")
>>> george = Author.objects.create(name="George")
>>> ringo = Author.objects.create(name="Ringo")
>>> entry.authors.add(john, paul, george, ringo)

4. 查询语句

通过QuerySet来构建查询,获取数据。

关于Query Set,可查看:https://blog.csdn.net/youyou1543724847/article/details/85940565

在Django中,QuerySet表示数据库中数据的集合。QuerySet可包括0个或多个filter,用于缩小数据范围。QuerySet表示一个select语句,而filter表示where或是limit。
(1)直接获取所有元素

all_entries = Entry.objects.all()

(2)过滤数据

Entry.objects.filter(pub_date__year=2006)

常用的过滤函数包括:

    filter(**kwargs):返回满足条件的
    exclude(**kwargs):返回不满足条件的
    get(**kargs):返回满足条件的记录。当记录不存在或是多条都满足时,会抛出异常

其中**kwargs参数形式如下:

field__lookuptype=value  (field为model中的字段名字;当field为外键时,可以添加 _id后缀)

例如:
Entry.objects.filter(pub_date__lte='2006-01-01')

等价于:
SELECT * FROM blog_entry WHERE pub_date <= '2006-01-01';

支持的lookuptype包括:exact,iexact, contains,icontians, startswith, endwith等。

当需要在多表关系中进行查询搜索时(对于sql的join),字段名字格式为本model的字段名字__相关连的model中的字段名字(field name of related fields across models, separated by double underscores, until you get to the field you want)。例如:

Entry.objects.filter(blog__name='Beatles Blog')

该关系扩展可以是多级的(即多表联合查询)

另外,也支持反向搜索(使用小写的model名称)。例如:获取所有的blog,该blog至少有一个entry的headline包含‘Lennon’(blog和author通过entry表存储管理关系)

 Blog.objects.filter(entry__headline__contains='Lennon')

另外,需要注意的是对QuerySet进行filter处理后返回的还是一个QuerySet对象,因此,可将filter 连着使用,形成filter 链。如:

>>> Entry.objects.filter(
...     headline__startswith='What'
... ).exclude(
...     pub_date__gte=datetime.date.today()
... ).filter(
...     pub_date__gte=datetime.date(2005, 1, 30)
... )

注意:某次对QuerySet进行filter时,都会重新构建一个新的QuerySet。

Django中的QuerySet是懒加载的,即构建一个QuerySet不会立即导致数据中的操作(不会立即和数据库交互,完成数据查询),直到QuerySet 被Evaluate,才会导致数据库查询操作(关于什么操作导致QuerySet被evaluate,请查看:https://docs.djangoproject.com/zh-hans/2.1/ref/models/querysets/#when-querysets-are-evaluated)。

5. 删除对象

delete语句

e.delete()

批量删除:

 Entry.objects.filter(pub_date__year=2005).delete()

5. 其他

5.1 model 元数据

通过使用内部类的形式来给model 添加元数据。例如:

from django.db import models

class Ox(models.Model):
    horn_length = models.IntegerField()

    class Meta:
        ordering = ["horn_length"]
        verbose_name_plural = "oxen"
        db_table =“ox_info"

更多信息,请查看:https://docs.djangoproject.com/zh-hans/2.1/ref/models/options/

5.2 model 属性

5.2.1 model.objects

model的最重要的属性就是Manager。Django通过Manager接口和来数据库进行交互,完成从数据库中获取数据实例的能力。如果没有自定义新的Manager的话,默认的Manger属性名字就是objects

5.3 model 方法

通过自定义一些模型方法(行级别的)来对表中的某条数据进行操作(相对而言,Manager的方法是表级别的,即对某张表进行整体操作,如表数据过滤)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值