Django models 基础
Django models 基础
什么是ORM呢?
对象关系映射(Object Relational Mapping),它的实质就是将关系数据(库)中的业务数据用对象的形式表示出来,并通过面向对象(Object-Oriented)的方式将这些对象组织起来,实现系统业务逻辑的过程。
在ORM过程中最重要的概念是映射(Mapping),通过这种映射可以使业务对象与数据库分离。从面向对象来说,数据库不应该和业务逻辑绑定到一起,ORM则起到这样的分离作用,使数据库层透明,开发人员真正的面向对象。
简而言之,用类和函数操作数据库。
`优点:
- 实现了代码与数据操作的解耦合
- 不需自己写原生sql, 提高开发效率
- 防止SQL注入, 通过对象操作的方式,默认就是防止sql注入的。
缺点:
- 牺牲性能, 对象到原生SQL势必会有转换消耗,对性能有一定的影响
- 复杂语句力不从心, 一些复杂的sql语句,用orm对象操作的方式很难实现,就还得用原生sql
`
字段:
AutoField #An IntegerField that automatically increments according to available IDs
BigAutoField # 1到9223372036854775807
BigIntegerField #-9223372036854775808到9223372036854775807
BinaryField #A field to store raw binary data. It only supports bytes assignment
BooleanField
CharField
DateField #e.g 2019-04-27
DateTimeField #e.g 2019-04-27 17:53:21
DecimalField
DurationField #storing periods of time ,e.g [DD] [HH:[MM:]]ss[.uuuuuu]"
EmailField
FileField #存储文件
FloatField
ImageField #Inherits all attributes and methods from FileField, but also validates that the uploaded object is a valid image.
IntegerField #-2147483648到的值2147483647
GenericIPAddressField #IP地址,支持ipv4
NullBooleanField #Like a BooleanField, but allows NULL as one of the options
PositiveIntegerField #Like an IntegerField, but must be either positive or zero (0). Values from 0 to 2147483647
PositiveSmallIntegerField #only allows positive values from 0 to 32767
SlugField # A slug is a short label for something, containing only letters, numbers, underscores or hyphens.
SmallIntegerField 从-32768到32767
TextField #A large text field.
TimeField #A time, represented in Python by a datetime.time instance.
URLField
UUIDField #A field for storing universally unique identifiers. Uses Python’s UUID class.
外键:
ForeignKey # 外键关联
ManyToManyField #多对多
OneToOneField # 1对1
字段常用参数:
null #If True, Django will store empty values as NULL in the database. Default is False.
blank #If True, the field is allowed to be blank. Default is False.
db_column #The name of the database column to use for this field. If this isn’t given, Django will use the field’s name.
db_index #If True, a database index will be created for this field.
default #The default value for the field. This can be a value or a callable object. If callable it will be called every time a new object is created.
editable # django admin中用,后面讲
help_text # django admin中用,后面讲
primary_key # If True, this field is the primary key for the model.
unique #If True, this field must be unique throughout the table
unique_for_date #Set this to the name of a DateField or DateTimeField to require that this field be unique for the value of the date field. For example, if you have a field title that has unique_for_date="pub_date", then Django wouldn’t allow the entry of two records with the same title and pub_date.
unique_for_month #Like unique_for_date, but requires the field to be unique with respect to the month.
unique_for_year
verbose_name #A human-readable name for the field. If the verbose name isn’t given, Django will automatically create it using the field’s attribute name
特殊字段:
An iterable (e.g., a list or tuple) consisting itself of iterables of exactly two items (e.g. [(A, B), (A, B) ...]) to use as choices for this field.
class Student(models.Model):
YEAR_IN_SCHOOL_CHOICES = (
('FR', 'Freshman'),
('SO', 'Sophomore'),
('JR', 'Junior'),
('SR', 'Senior'),
)
year_in_school = models.CharField(
max_length=2,
choices=YEAR_IN_SCHOOL_CHOICES,
default=FRESHMAN,
)
ForeignKey.on_delete
当一条记录关联的外键纪录被删除时,django 也会根据外键关联限制的配置来决定如何处理当前这条纪录。举例,如果你有个可以为null的外键关联,并且你想在本纪录关联的数据被删除时,把当前纪录的关联字段设为null,那就配置如下
user = models.ForeignKey(
User,
on_delete=models.SET_NULL,
blank=True,
null=True,
)
- CASCADE——Cascade deletes. Django emulates the behavior of the SQL constraint ON DELETE CASCADE and also deletes the object containing the ForeignKey.
- PROTECT——Prevent deletion of the referenced object by raising ProtectedError, a subclass of django.db.IntegrityError.
- SET_NULL——Set the ForeignKey null; this is only possible if null is True.
- SET_DEFAULT——Set the ForeignKey to its default value; a default for the ForeignKey must be set.
配置Django数据库连接信息
Django支持多种数据库,Sqlite、Mysql、Oracle、PostgreSQL,默认的是小型文件数据库Sqlite、
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'my_db',
'USER': 'mydatabaseuser',
'PASSWORD': 'mypassword',
'HOST': '127.0.0.1',
'PORT': '3306',
}
}
不过注意,python3 连接mysql得使用pymysql,MysqlDB模块300年没更新了,但django默认调用的还是MySQLdb, so pymysql有个功能可以让django以为是用了MySQLdb. 即在项目目录下的__init__.py中加上句代码就好
import pymysql
pymysql.install_as_MySQLdb()
同步数据库
- 生成同步文件, django自带一个专门的工具叫migrations, 负责把你的orm表转成实际的表结构,它不旦可以帮自动创建表,对表结构的修改,比如增删改字段、改字段属性等也都能自动同步。只需通过下面神奇的命令。
python manage.py makemigrations - 同步到数据
python manage.py migrate
增删改查
增:
from app1 import models
def orm(request):
models.user_info.objects.create(user_name='anna',password='alex')
#方法1
obj=models.user_info(user_name='anweiwei',password='123')
obj.save()
#方法2
d={'user_name':'lucy','password':'234'}
obj1 = models.user_info(**d)
obj1.save()
#方法3
return HttpResponse('orm')
查:
models.Book.objects.all()[:2]
models.Book.objects.get(id=2)
models.Book.objects.all().first() .last()
models.Book.objects.filter(author='alex').values('name',)
models.Book.objects.filter(author='alex').values_list('name', 'price')
models.Book.objects.exclude(author='alex').values('author')
models.Book.objects.all().values('name').distinct().count()
models.Book.objects.all().filter(author__contains='a').values('author') #__用来跨表查询
Book.objects.all().filter(price__gte=80).values('price')#__用来表示查询条件
filter支持很多过滤条件(包含contains):
Entry.objects.get(headline__contains='Lennon')
in
Entry.objects.filter(id__in=[1, 3, 4])
gt大于gte lt小于lte小于等于
Entry.objects.filter(id__gt=4)
startswith
Entry.objects.filter(headline__startswith='Lennon')
istartswith endswith isendswith
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))
date
Entry.objects.filter(pub_date__date=datetime.date(2005, 1, 1))
year month day week
Entry.objects.filter(pub_date__year=2005)
isnull
Entry.objects.filter(pub_date__isnull=True)
regex regex 大小写不敏感
Entry.objects.get(title__regex=r'^(An?|The) +')
改删
# 批量修改
models.Account.objects.filter(username='elina').update(password="Luffy#21")
# 单条修改
obj = models.Account.objects.get(username='linux')
obj.username = 'python'
obj.save()
# 批量删除
models.User.objects.get(password='oldboy').delete()
# 单条删除
obj = models.User.objects.get(id=3)
obj.delete()
数据返回后的展示
- Queryset获取的是列表类型的,需要遍历出来,所以需要first() [0]
- Object.all()取到的是对象,通过点来调用
- Object.all().values(‘name’)取到的是包含字典的列表,通过索引获取值
- Object.all().values_list()取到的是包含元组的列表。也通过索引获取值
order_by()
Entry.objects.filter(pub_date__year=2005).order_by('-pub_date', 'headline')
reverse()
my_queryset.reverse()[:5]
ORM对象操作
#单表对象操作
o = models.Article.objects.all()[0]
o.tilte
#外键关联
>>> o.account.username
'jack'
>>> o.account.username = rain
#外键反向关联操作
>>> a = models.Account.objects.get(username='alex')
>>> a.article_set.all()
<QuerySet [<Article: 你好,2018>]>
>>> a.article_set.select_related()
<QuerySet [<Article: 你好,2018>]>
#多对多操作
>>> o = models.Article.objects.all()[1]
>>> o.tags.all()
<QuerySet [<Tag: 投资>, <Tag: 科技>]>
#多对多反向操作
>>> t = models.Tag.objects.get(name="投资")
>>> t.article_set.all()
<QuerySet [<Article: 你好,2018>, <Article: 粉丝超过10万后,我经历了抖音盗号风波>]>

浙公网安备 33010602011771号