在Django中,可以在models.py中如下样式定义模型;
from django.db import models
class Acommentb(models.Model): #继承于models.Model
title = models.CharField(max_length=200)
slug = models.CharField(max_length=200)
body = models.TextField()
pub_date = models.DateTimeField(default = timezone.now)
class Meta:
ordering = ('-pub_date',)
class __unicode__(self): #使用unicode而不使用str可以解决旧版本中的中文显示问题..新版好像没此问题..
return self.title
然后通过 python manage.py makemigrations appname 在appname文件夹下创建了”迁移”,即把models.py中的模型记录为sql语句,
创建的文件就在migrations文件夹中可以查看0001_initial.py,这时候django还没有建立真正的数据库
然后再通过 python manage.py migrate 进行迁移,这时候django会把”迁移”映射到真正的数据库上,数据库默认为sqlite,
也可以在settings.py中设置选择其它的SQL数据库,比如使用mysql
DATABASES = {
‘default’: {
‘ENGINE’:’django.db.backends.mysql’, #django的mysql驱动
‘NAME’: ‘SchoolInfo’,
‘USER’: ‘root’,
‘PASSWORD’: ”,
‘HOST’: ‘127.0.0.1’,
‘PORT’: ‘3306’,
}
}
还有一点,如果想使用SQL中的外键关系可以使用django中的,”一对一关系”,”一对多关系”,“多对多关系”进行替代,该不需要对应字段和类型仅作为一个关联
写完模型创建迁移后可以使用 python manage.py sqlmigrate appname 查看该APP模型所对应的SQL语句
这里展示下,常用的字段属性:
字段选项 | 说明 |
null | 此字段是否接受存储空值NULL,默认是False |
blank | 此字段是否接受存储空白内容,默认值是False |
choices | 以选项的方式(只有固定内容的数据可以选用)作为此字段的候选值 |
default | 输入此字段的默认值 |
help_text | 字段的帮助信息 |
primary_key | 把此字段设置为数据库表中的主键KEY,默认值为False |
unique | 设置此字段是否为唯一值,默认值为False |
max_length | 字段值最大长度 |
字段合集:
AutoField(Field)
- int自增列,必须填入参数 primary_key=True
BigAutoField(AutoField)
- bigint自增列,必须填入参数 primary_key=True
注:当model中如果没有自增列,则自动会创建一个列名为id的列
from django.db import models
class UserInfo(models.Model):
# 自动创建一个列名为id的且为自增的整数列
username = models.CharField(max_length=32)
class Group(models.Model):
# 自定义自增列
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
SmallIntegerField(IntegerField):
- 小整数 -32768 ~ 32767
PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
- 正小整数 0 ~ 32767
IntegerField(Field)
- 整数列(有符号的) -2147483648 ~ 2147483647
PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
- 正整数 0 ~ 2147483647
BigIntegerField(IntegerField):
- 长整型(有符号的) -9223372036854775808 ~ 9223372036854775807
BooleanField(Field)
- 布尔值类型
NullBooleanField(Field):
- 可以为空的布尔值
CharField(Field)
- 字符类型
- 必须提供max_length参数, max_length表示字符长度
TextField(Field)
- 文本类型
EmailField(CharField):
- 字符串类型,Django Admin以及ModelForm中提供验证机制
IPAddressField(Field)
- 字符串类型,Django Admin以及ModelForm中提供验证 IPV4 机制
GenericIPAddressField(Field)
- 字符串类型,Django Admin以及ModelForm中提供验证 Ipv4和Ipv6
- 参数:
protocol,用于指定Ipv4或Ipv6, 'both',"ipv4","ipv6"
unpack_ipv4, 如果指定为True,则输入::ffff:192.0.2.1时候,可解析为192.0.2.1,开启此功能,需要protocol="both"
URLField(CharField)
- 字符串类型,Django Admin以及ModelForm中提供验证 URL
SlugField(CharField)
- 字符串类型,Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、连接符(减号)
CommaSeparatedIntegerField(CharField)
- 字符串类型,格式必须为逗号分割的数字
UUIDField(Field)
- 字符串类型,Django Admin以及ModelForm中提供对UUID格式的验证
FilePathField(Field)
- 字符串,Django Admin以及ModelForm中提供读取文件夹下文件的功能
- 参数:
path, 文件夹路径
match=None, 正则匹配
recursive=False, 递归下面的文件夹
allow_files=True, 允许文件
allow_folders=False, 允许文件夹
FileField(Field)
- 字符串,路径保存在数据库,文件上传到指定目录
- 参数:
upload_to = "" 上传文件的保存路径
storage = None 存储组件,默认django.core.files.storage.FileSystemStorage
ImageField(FileField)
- 字符串,路径保存在数据库,文件上传到指定目录
- 参数:
upload_to = "" 上传文件的保存路径
storage = None 存储组件,默认django.core.files.storage.FileSystemStorage
width_field=None, 上传图片的高度保存的数据库字段名(字符串)
height_field=None 上传图片的宽度保存的数据库字段名(字符串)
DateTimeField(DateField)
- 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]
DateField(DateTimeCheckMixin, Field)
- 日期格式 YYYY-MM-DD
TimeField(DateTimeCheckMixin, Field)
- 时间格式 HH:MM[:ss[.uuuuuu]]
DurationField(Field)
- 长整数,时间间隔,数据库中按照bigint存储,ORM中获取的值为datetime.timedelta类型
FloatField(Field)
- 浮点型
DecimalField(Field)
- 10进制小数
- 参数:
max_digits,小数总长度
decimal_places,小数位长度
BinaryField(Field)
- 二进制类型
对应关系:
‘AutoField’: ‘integer AUTO_INCREMENT’,
‘BigAutoField’: ‘bigint AUTO_INCREMENT’,
‘BinaryField’: ‘longblob’,
‘BooleanField’: ‘bool’,
‘CharField’: ‘varchar(%(max_length)s)’,
‘CommaSeparatedIntegerField’: ‘varchar(%(max_length)s)’,
‘DateField’: ‘date’,
‘DateTimeField’: ‘datetime’,
‘DecimalField’: ‘numeric(%(max_digits)s, %(decimal_places)s)’,
‘DurationField’: ‘bigint’,
‘FileField’: ‘varchar(%(max_length)s)’,
‘FilePathField’: ‘varchar(%(max_length)s)’,
‘FloatField’: ‘double precision’,
‘IntegerField’: ‘integer’,
‘BigIntegerField’: ‘bigint’,
‘IPAddressField’: ‘char(15)’,
‘GenericIPAddressField’: ‘char(39)’,
‘NullBooleanField’: ‘bool’,
‘OneToOneField’: ‘integer’,
‘PositiveIntegerField’: ‘integer UNSIGNED’,
‘PositiveSmallIntegerField’: ‘smallint UNSIGNED’,
‘SlugField’: ‘varchar(%(max_length)s)’,
‘SmallIntegerField’: ‘smallint’,
‘TextField’: ‘longtext’,
‘TimeField’: ‘time’,
‘UUIDField’: ‘char(32)’,
二、根据旧的数据库自动生成模型
如果想通过旧的数据库集成在django中也是可以的,django中有这样的自动生成模型的工具,即inspectdb.
inspectdb适用于PostgreSQL,MySQL和SQLite。外键检测仅适用于PostgreSQL和某些类型的MySQL表。
python manage.py inspectdb 可以通过这句话来看输出 #需要在settings.py中指定数据库
然后通过输出重定向将他保存为模型
python manage.py inspectdb > models.py 生成模型后确认无误后将该文件放在app文件夹中并将该app放在install_apps中
然后通过 python manage.py migrate 安装核心django表,记录管理员权限和内容类型等.导入核心django表后就可以
python manage.py createsuperuser 来创建后台管理员帐号了,之后就能进入/admin页面GUI式管理数据库了
[注] 如果表结构比较复杂,可能会出现
CustomerProfile.user: (fields.E304) Reverse accessor for ‘Fielname’ clashes with reverse accessor for ‘Fielname’.
如果出现这种错误,只需要在冲突的名字定义中加个 related_name=”唯一名” 即可,比如:
user = models.OneToOneField(User, related_name=”custom_user_profile”, primary_key=True)
三、修改表结构
python manage.py migrate your_app_name zero 删除表结构
在Django中修改了表结构可以使用如下命令同步到数据库:
python manage.py makemigrations
python manage.py migrate
如果如上命令出现了错误,可以如下命令查看上面命令生成的sql语句:
python manage.py sqlmigrate your_app_name 0001
投机取巧可以自己直接在数据库中执行django生成的sql语句,然后再执行迁移。
四、数据的操作
querySet.distinct() 去重复
__exact 精确等于 like ‘aaa’
__iexact 精确等于 忽略大小写 ilike ‘aaa’
__contains 包含 like ‘%aaa%’
__icontains 包含 忽略大小写 ilike ‘%aaa%’,但是对于sqlite来说,contains的作用效果等同于icontains。
__gt 大于
__gte 大于等于
__lt 小于
__lte 小于等于
__in 存在于一个list范围内
__startswith 以…开头
__istartswith 以…开头 忽略大小写
__endswith 以…结尾
__iendswith 以…结尾,忽略大小写
__range 在…范围内
__year 日期字段的年份
__month 日期字段的月份
__day 日期字段的日
__isnull=True/False
from django.db import connection
cursor = connection.cursor()
cursor.execute(“””
… SELECT DISTINCT first_name
… FROM people_person
… WHERE last_name = %s”“”, [‘Lennon’])
row = cursor.fetchone()
print row
[‘John’]
五、注意事项
从数据库反向生成的表,如果要修改的话,得把模型类中的内部类Meta中的managed = False删掉,并且
删除migrate文件夹(因为之前是False之后好像执行迁移也不会更改…神奇吧)
内部类Meta的详细作用可以参考:
http://blog.chinaunix.net/uid-21633169-id-4374219.html