码迷,mamicode.com
首页 > 其他好文 > 详细

django学习の模型

时间:2015-10-30 18:45:22      阅读:270      评论:0      收藏:0      [点我收藏+]

标签:

orm:对象数据库和模型的映射。如果想以简单的方式去操作数据库,例如用类的方式去操作,就像 p = Person.get(id = 1),那么就必须使得代码和数据库的结构具有映射关系,实现这种关系,你可以事先就预先好一套创建类以及到数据库表的对应关系,也可以实时追踪数据库结构,很明显,第二张方式实现起来比较影响效率,所以大多数时候,在一开始,就用模型来对应数据库的一种关系,然后保证它们结构统一,就可以实现高度封装sql语句,用简洁明了的方式去操作业务逻辑,就像p = Person.get(id = 1),你就获得了数据库中person表的一个实例(信息)。当然,自己实现这样一个封装框架是比较复杂,django有强大的模型系统.

模型用类来表示数据库的表,每一个类属性是表中的一个字段,当然这个属性必须是django给出的field子类。先来做一个非常简单的模型。配置好django,创建好django项目以后。

#-*- coding:utf-8 -*-
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.utils import timezone
# Create your models here.
class User(models.Model):
name = models.CharField(max_length=10)
sex = models.CharField(max_length=10)

这样,就得到了一个模型,这个模型会在数据库中创建一个user表,并且有一个name列,和sex列,他们都是varchar类型。modes提供了很多相应的field类型

CharField(max_lenght=10)中max_lenght是一个必须的字段,表示他的长度。如果需要一个无限长的较大文本,可以考虑用TextField,常用的字段有EmailField,

URLField,IPAddressField,BooleanField,NullBooleanField,FileField(保存文件),具体细节可以看官方文档,他们都是继承至Field类,在models块中。一般情况你可以用

IntegerField 表示数字,传入primary_key=True可以定义为主键

默认系统会自己生成主键。然后现在想写第二个类了,我们有了,User类,可以假设现在这一群User可能是几个团队的分子,并且一人只能参加一个团队,那么先得有个Team

#-*- coding:utf-8 -*-
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.utils import timezone
# Create your models here.
class User(models.Model):
    name = models.CharField(max_length=10)
    sex = models.CharField(max_length=10)

class Team(models.Model):
    name = models.CharField(max_length=10)

 

这样就多了一个Team类,按一开始的设定要用到一对多的关系外键,所以要用ForeignKey(Team),像这样
#-*- coding:utf-8 -*-
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.utils import timezone
# Create your models here.
class User(models.Model):
    name = models.CharField(max_length=10)
    sex = models.CharField(max_length=10)
    team = models.ForeignKey(Team)

class Team(models.Model):
    name = models.CharField(max_length=10)

但是如果现在同步会出错,因为Team在User下面,解释时还没有,会报错,一般输入python manage.py makemigrations创建一个历史迁移文件,然后migrate执行迁移,就会同步到数据库.为了不报错,应该是这样:

#-*- coding:utf-8 -*-
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.utils import timezone
# Create your models here.


class Team(models.Model):
    name = models.CharField(max_length=10)

class User(models.Model):
    name = models.CharField(max_length=10)
    sex = models.CharField(max_length=10)
    team = models.ForeignKey(Team)

这个时候,user这个群体可能是好友,好友的关系是多对多,一个人可能有很多好友,并且每个好友也有很多好友,所以有多对多的关系,如下:

#-*- coding:utf-8 -*-
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.utils import timezone
# Create your models here.
class User(models.Model):
    name = models.CharField(max_length=10)
    sex = models.CharField(max_length=10)
    team = models.ForeignKey(Team)
    friend = models.ManyToManyField(self)

class Team(models.Model):
    name = models.CharField(max_length=10)

‘self‘表示是自己,如果是Team传入类变量即可,同样适用于外键。django默认表示如果你是我好友,那我也是你好友,用symmetrical = False参数可以打破这种对称,如果需要可以用在ManyToManyField。

如果有的Team比较特殊,他们不仅有名字,还有特别的字段,比如坦克,但是它们又是Team,可以用继承,也可以用OneToOneField(Team).用继承如下:

#-*- coding:utf-8 -*-
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.utils import timezone
# Create your models here.
class User(models.Model):
    name = models.CharField(max_length=10)
    sex = models.CharField(max_length=10)
    team = models.ForeignKey(Team)
    friend = models.ManyToManyField(self)

class Team(models.Model):
    name = models.CharField(max_length=10)

class SuperTeam(Team):
    tank = models.CharField(max_length=10)

这样可能看不出用继承有什么优势,如果Team类有一万个属性,而SuperTeam有一万零一,前一万个和Team一样,就可以用继承。

有时候继承可能不需要Team,就是实际上Team用不到,那么可以把Team设置成抽象继承类,数据库就不会创建这张表,它只是为了继承而存在的,在Team的Meta嵌套类里面

定义abstruct = True,就像这样:

#-*- coding:utf-8 -*-
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.utils import timezone
# Create your models here.
class User(models.Model):
    name = models.CharField(max_length=10)
    sex = models.CharField(max_length=10)
    team = models.ForeignKey(Team)
    friend = models.ManyToManyField(self)

class Team(models.Model):
    name = models.CharField(max_length=10)
    class Meta:
        abstract = True

class SuperTeam(Team):
    tank = models.CharField(max_length=10)

嵌套类细节可参考官方文档

多对多关系实际上是在数据库建立第三张表来保存这种关系,有时候如果希望这张表也有字段,那就可以自己来写这张表,比如User成为好友的时间。

#-*- coding:utf-8 -*-
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.utils import timezone
# Create your models here.
class User(models.Model):
    name = models.CharField(max_length=10)
    sex = models.CharField(max_length=10)
    team = models.ForeignKey(Team)
    friend = models.ManyToManyField(self,through=FriendShip)

class Team(models.Model):
    name = models.CharField(max_length=10)
    class Meta:
        abstract = True

class SuperTeam(Team):
    tank = models.CharField(max_length=10)

class FriendShip(models.Model):
    user = models.ForeignKey(User)
    friend = models.ForeignKey(User)
    data_became_friend = models.DateTimeField(default=timezone.now)

先通过through指定想成为好友关系的表,然后第三种表中定义这种关系,如果是不同类之间的多对多,那么也一样,只是有一个外键指向另一张成为好友的表就行了,然而这里面有个矛盾,假如关系表里面外键User,像这个例子,多于三个,像这样

class FriendShip(models.Model):
user = models.ForeignKey(User,relat_name = ‘user_set‘)
friend = models.ForeignKey(User)
three = models.ForeignKey(User)
data_became_friend = models.DateTimeField(default=timezone.now)

django并没有智能到可以分辨哪一个字段是他想要对应的,因为本来是两者的好友关系,莫名其妙多了第三种,这时候需要在外键里面加入through_fields = (‘user‘,‘friend‘)参数,同理如果是不同类的多对多,也应该按顺序写参数。

 

至于操作,django提供了manage,和QuerySet,这都是什么鬼啊。

而objects就是每个类只想manage的变量,manage获得,提供了all filter exclude get 方法,返回Queryset对象,Queryset本身也提供了manage的方法,所以最后是支持连缀操作的,就像,get(id =1).filter(name__contains = "Tree"),django也提供了很多像__contains这样的过滤操作,只需名字__contains就可以了。修改有update,或者直接属性赋值修改,这种修改把没有修改的值也修改一遍,按照原来的值。最后save函数会把结果在数据库执行,这是一种惰性机制,我并不会第一时间的执行。



 



django学习の模型

标签:

原文地址:http://www.cnblogs.com/wuweixin/p/4923771.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!