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()

同步数据库

  1. 生成同步文件, django自带一个专门的工具叫migrations, 负责把你的orm表转成实际的表结构,它不旦可以帮自动创建表,对表结构的修改,比如增删改字段、改字段属性等也都能自动同步。只需通过下面神奇的命令。python manage.py makemigrations
  2. 同步到数据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万后,我经历了抖音盗号风波>]>
posted @ 2020-03-09 21:11  Neroi  阅读(113)  评论(0)    收藏  举报