Django--ORM操作

ORM操作:

mysql> create database django_db charset utf8;  特别提示MYSQL数据库必须先创建数据库
Query OK, 1 row affected (0.03 sec)

https://docs.djangoproject.com/en/1.10/

设置数据库表:多对多字段设置默认值为空时--无效
WARNINGS:
bbs.Article.tags: (fields.W340) null has no effect on ManyToManyField.

创建超级用户:弱密码校测(8位以上)zhangsong/1q2w3e!@#
D:python培训our_pythondemo_django_server>python manage.py createsuperuser
System check identified some issues:
WARNINGS:
bbs.Article.tags: (fields.W340) null has no effect on ManyToManyField.
Username (leave blank to use 'admin'): zhangsong
Email address:
Password:
Password (again):
This password is too short. It must contain at least 8 characters.
Password:
Password (again):
Superuser created successfully.


D:python培训our_pythondemo_django_server>python manage.py shell
Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:01:18) [MSC v.1900 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>>>>> from app01 import models

CRUD---create、revise、update、delete增删改查
objects.create
b1 = app01.models.Book(name="linux"...)
b1.save()
objects.update
objects.first第一个
objects.last最后一个
objects.filter返回列表
objects.all返回对象列表
objects.get 返回单个对象或者错误(DoesNotExist不存在错误、MultipleObjectsReturned返回多个对象的错误)
objects.get_or_create 返回False表示查询对象存在未创建,返回True表示查询对象不存在并成功创建,返回IntegrityError表示不存在,但创建时数据不完善造成创建失败
objects.delete

新增:
>>> models.Publisher.objects.create(name='qinghua',website="http://qinghua.edu.com.cn")
<Publisher: qinghua>
>>> models.Publisher.objects.create(name='youdian',website="http://youdian.edu.com.cn")
<Publisher: youdian>

(1)有外键时先创建外键:外键不能为空(数据库会默认创建ID字段publisher_id=1表示publisher表的id为1的一行记录)
jango.db.utils.IntegrityError: NOT NULL constraint failed: app01_book.publisher_id
>>> models.Book.objects.create(name='math',price=12,pub_date='2013-12-12',publisher_id=1)
<Book: math>
>>> models.Book.objects.create(name='wu',price=12,pub_date='2013-12-12',publisher_id=1)
<Book: wu>
>>> models.Book.objects.create(name='le',price=32,pub_date='2003-12-12',publisher_id=2)
<Book: le>

(2)含有多对多字段的表新增数据、必须先创建对应的对象,最后插入多对多的字段(其他字段先创建、最后补增多对多字段)
models.Book.objects.create(name='math',price=12,pub_date='2013-12-12',publisher_id=1,authors_id=1)#authors为多对多字段
多对多报错:
ValueError: "<Book: math>" needs to have a value for field "book" before this many-to-many relationship can be used.
obj = models.Book.objects.create(name='math',price=12,pub_date='2013-12-12',publisher_id=1) #创建对象
obj.authors.add(1,2) #对象中增添authors字段并赋值
obj.authors.remove(1,2) #对象中删除authors字段
obj.save() #保存

查询:
外键查询:publisher为外键
obj = models.Book.objects.create(name='math',price=12,pub_date='2013-12-12',publisher_id=1)
obj.publisher.name #即可查出obj这个对象关联的外键的记录中的name字段的值
>>> obj.publisher.name
'qinghua'
查询部分字段:
>>> models.Book.objects.values("name","price")
<QuerySet [{'name': 'python', 'price': 12}, {'name': 'linux', 'price': 122}, {'name': 'java', 'price': None}]>


get不存在:
app01.models.DoesNotExist: Book matching query does not exist.

get_or_create不存在则创建,返回值True表示已经创建,False表示未创建
>>> models.Book.objects.get_or_create(name='java',publisher_id=1,pub_date="2011-03-15")
(<Book: java>, True)
>>> models.Book.objects.get_or_create(name='java')
(<Book: java>, False)

__contains包含
__icontains包含 忽略大小写
__startswith 开始
__endswith 结束
__range 范围
__isnull 为空
__regex 正则表达式
__iregex 正则表达式 忽略大小写

>>> models.Book.objects.filter(name__contains='java')
<QuerySet [<Book: java>]>
>>> models.Book.objects.filter(name__contains='jAva')
<QuerySet []>
>>> models.Book.objects.filter(name__icontains='jAva')
<QuerySet [<Book: java>]>

>>> models.Book.objects.filter(pub_date__range=("2011-01-01","2222-01-01"))
<QuerySet [<Book: python>, <Book: linux>, <Book: java>]>
>>> models.Book.objects.filter(pub_date__year=2011)
<QuerySet [<Book: java>]>

>>> models.Book.objects.filter(pub_date__isnull=False)
<QuerySet [<Book: python>, <Book: linux>, <Book: java>]>
>>> models.Book.objects.filter(pub_date__isnull=True)
<QuerySet []>

取反操作:
>>> models.Book.objects.exclude(price=None) #查询所有price不为空的对象
<QuerySet [<Book: python>, <Book: linux>]>

Aggregation(聚合)
聚合操作:(不统计包含null的数据)
>>> from django.db.models import Avg,Max,Min,Sum,Count
>>> models.Book.objects.all().count()
3
>>> models.Book.objects.all().aggregate(Sum("price"))
{'price__sum': 134}
>>> models.Book.objects.all().aggregate(Avg("price"))
{'price__avg': 67.0}

>>> models.Book.objects.all().aggregate(Max("price"))
{'price__max': 122}
>>> models.Book.objects.all().aggregate(Min("price"))
{'price__min': 12}

values后面跟分类的名称、annotate聚合统计
>>> models.Book.objects.values("publisher__name").annotate(Count("id"))
<QuerySet [{'id__count': 3, 'publisher__name': 'qinghua'}, {'id__count': 2, 'publisher__name': 'youdian'}]>

# The top 5 publishers, in order by number of books.
>>> pubs = models.Publisher.objects.annotate(num_books=Count('book')).order_by('-num_books')[:5]
>>> pubs[0].num_books
1323

output_field指定输出格式
>>> from django.db.models import F, FloatField, Sum
>>> Book.objects.all().aggregate(price_per_page=Sum(F('price')/F('pages'), output_field=FloatField()))
{'price_per_page': 0.4470664529184653}

其他操作:https://docs.djangoproject.com/en/1.9/topics/db/aggregation/

Q语句:
>>> from django.db.models import Q
>>> q1 = Q(pub_date__year="2016")
>>> q2 = Q(pub_date__year="2016") | Q(pub_date__year="2018")
>>> q3 = Q(pub_date__year="2016") | ~Q(pub_date__year="2018")
>>> q4 = Q(pub_date__year="2016") , Q(pub_date__year="2018")
>>> q1
<Q: (AND: ('pub_date__year', '2016'))>
>>> q2
<Q: (OR: ('pub_date__year', '2016'), ('pub_date__year', '2018'))>
>>> q3
<Q: (OR: ('pub_date__year', '2016'), (NOT (AND: ('pub_date__year', '2018'))))>
>>> q4
<Q: (AND: ('pub_date__year', '2016'),(AND: ('pub_date__year', '2018')))>
>>> models.Book.objects.filter(q3)
<QuerySet [<Book: python>, <Book: linux>, <Book: java>]>

F语句:
批量更新数据库
>>> from django.db.models import F
>>> from app01 import models
>>> models.Book.objects.values("price")
<QuerySet [{'price': 12}, {'price': 12}, {'price': 32}, {'price': 12}, {'price': 22}]>
>>> models.Book.objects.update(price=F("price")+15)
5
>>> models.Book.objects.values("price")
<QuerySet [{'price': 27}, {'price': 27}, {'price': 47}, {'price': 27}, {'price': 37}]>

(数据迁移)将同一个表的某一个字段的值,全部传给另一个字段
>>> from django.db.models import F
>>> from app01 import models
>>> models.Book.objects.update(memo=F("price")) --->将price字段的值全部赋值给memo字段

(数据比较)同一个表不同字段进行比较
>>> from django.db.models import F
>>> models.Book.objects.filter(memo__gt=F('price'))

 form表单

后端生成前端需要的数据和样式,前端仅负责调用并展示--->

app中建forms表单(创建位置没有要求,能找到即可),在forms中建一个类(AmForm),类中写明具体返回的字段名称和样式;
views视图中导入视图(from app01.froms import forms并实例化,form = AmForm(),并以参数(字典)的形式传给前端);
前端输入数据给后端,先提交给表单验证,将数据提交给表单form = AmForm(request.POST),验证数据合法性form.is_valid(),验证后的数据传给cleaned_data属性进行格式化数据(form.cleaned_data),验证失败的错误放入form.errors中;
(样式和逻辑验证全部在app下的forms文件中添加);
样式添加在attrs字段中,格式为字典;
自定义逻辑验证,增加clean_colname(colname为字段名称)的函数,并在函数中验证,验证完返回验证的字段,否则后端业务拿到数据为None;

原文地址:https://www.cnblogs.com/feiyu_Team/p/6654220.html