实用型的DJANGO ORM
2016-07-26 16:29
363 查看
比较深入一点的内容,需要用时,用心看看。
URL:
https://www.sitepoint.com/doing-more-with-your-django-models/
So you have a Django app, but sometimes you find the Django models too constraining. We will guide you through using Django models to get more out of them. This is an intermediate tutorial, as some familiarity with Django is assumed. For example, we assume you know how to write a basic Django model, you know how to override Python methods, as well as how
We will talk about these topics
Proxy Models
Overriding
Using signals
Optimizing your DB access using
Advanced lookups using Q objects
Aggregation and Annotation
Using F() expressions
Lets look at some common operations you may want to perform using Django and how the above Django functionality will help you achieve them.
Now in your
You want to increment the
Django emits signals before taking any action. You can connect your functions to signals to take action when interesting stuff happens. Django comes with two signals
Now you are iterating over a Subject queryset, and you want the sum of all the Score objects which have a foreign key to current object. You can do this by getting individual
assuming that the app is called
We have a model like:
So, if you want all Score objects for Physics which have either score > 95 or are in 2012.
We used the double underscore notation to apply filters and joined them together using boolean operators. You can pass them to
E.g., if you want the maximum, minimum, and average of
For more, see the guide on aggregation
We have a model like this:
You want to find all departments which have more managers than employees.
F objects support addition, subtraction, multiplication, division so you can do things like
URL:
https://www.sitepoint.com/doing-more-with-your-django-models/
https://www.sitepoint.com/doing-more-with-your-django-models/
So you have a Django app, but sometimes you find the Django models too constraining. We will guide you through using Django models to get more out of them. This is an intermediate tutorial, as some familiarity with Django is assumed. For example, we assume you know how to write a basic Django model, you know how to override Python methods, as well as how
.filterand
.excludework.
We will talk about these topics
Proxy Models
Overriding
.save
Using signals
Optimizing your DB access using
.extra
Advanced lookups using Q objects
Aggregation and Annotation
Using F() expressions
Lets look at some common operations you may want to perform using Django and how the above Django functionality will help you achieve them.
How can I get two Python representation of the same Database table?
You may want to have two model classes corresponding to a single database table. For example,admin.site.registerallows a Model to be registered only once. However, you may want the same model twice in the Admin area. Proxy models can help you do that!
from django.contrib.auth.models import User class NewUser(User): class Meta: proxy = True
Now in your
admin.pyyou can register NewUser again and customize your ModelAdmin. (For example, if you want to show only some of the fields, add a custom ordering and so on).
How can I take action before saving a model to database?
Sometime you may have some denormalized data. Consider this model:class Poll(models.Model): ###... num_choices = models.PositiveIntegerField() class Choice(models.Model): poll = models.ForeignKey(Poll) ###...
You want to increment the
num_choicesbefore saving
Choice. You can do that by overriding
.savelike this.
def save(self, *args, **kwargs): self.poll.num_choices += 1 self.poll.save() super(Choice, self).save(*args, **kwargs)
How can I take action before saving the models to database if I didn’t write the model?
Overriding.saveis great when you are writing all the models. However for example you have a
Subscriptionmodel and when someone sings up they are assigned a subscription. However since you didn’t write the
Usermodel, you can not override the .save model.
Django emits signals before taking any action. You can connect your functions to signals to take action when interesting stuff happens. Django comes with two signals
pre_saveand
post_savewhich you can connect to.
from django.db.models.signals import pre_save from django.contrib.auth.models import User def subscription_handler(**kwargs): #Do something with the Subscription model pre_save.connect(subscription_handler, sender=User, dispatch_uid="subscription_handler")
How can I get related objects without hitting the database many times?
Assume we have these models:class Subject(models.Model): ###... class Score(models.Model): ###... subject = models.ForeignKey(Subject) score = models.PositiveIntegerField()
Now you are iterating over a Subject queryset, and you want the sum of all the Score objects which have a foreign key to current object. You can do this by getting individual
Scoreobjects and then summing them in Python, but it would be faster to do that in the database. Django has a method
.extrawhich allows you to insert arbitrary clauses in the sql generated by the queryset. For example here you can do
Subject.objects.extra(select={"total_scores": "select sum(score) from poll_score where poll_score.subject_id = poll_subject.id"})
assuming that the app is called
pollfor which the default names for tables are
poll_subjectand
poll_score.
How can you compose OR, NOT and other SQL operations?
By default Django will AND all criteria passed to the filtering methods. If you want to use OR/NOT operator, you will need to use Q objects.We have a model like:
class Score(models.Model): ###... subject = models.ForeignKey(Subject) score = models.PositiveIntegerField() date = models.DateField()
So, if you want all Score objects for Physics which have either score > 95 or are in 2012.
criteria = Q(subject__name="Physics") & (Q(score__gt=95)|Q(date__year=2012))
We used the double underscore notation to apply filters and joined them together using boolean operators. You can pass them to
.filter. (Or to
.exclude)
Score.objects.filter(criteria)
How can I get group_by type of operations?
Django provides two methods on its querysets –.aggregateand
.annotate. Aggregates convert the queryset in a dictionary on name, value pairs.
E.g., if you want the maximum, minimum, and average of
Scoreobjects. You can get them as
from django.db.models import Avg, Max, Min Score.objects.all().aggregate(Max('score'), Avg('score'), Min('score'))
For more, see the guide on aggregation
How can I compare within rows?
Django providesFobjects which are used to create queries which compare within rows.
We have a model like this:
class Department(models.Model): ##... num_employees = models.PositiveIntegerField() num_managers = models.PositiveIntegerField()
You want to find all departments which have more managers than employees.
from django.db.models import F Department.objects.filter(num_managers__gt=F('num_employees'))
F objects support addition, subtraction, multiplication, division so you can do things like
Department.objects.filter(num_employees__lt=F('num_managers')*2)
相关文章推荐
- golang两种调用rpc的方法
- Django信号系统简介
- 什么是repo
- Django中间件
- kinect driver install (ubuntu 14.04 & ros-indigo)
- 批量删除mongo collections
- 如何查看google chrome 插件源码
- 如何查看google chrome 插件源码
- Google APAC----Africa 2010, Qualification Round(Problem C. T9 Spelling)----Perl 解法
- Google APAC----Africa 2010, Qualification Round(Problem B. Reverse Words)----Perl 解法
- Google APAC----Africa 2010, Qualification Round(Problem A. Store Credit)----Perl 解法
- Django 静态资源url的设置
- 创意苹果LOGO灯iPhone6 Plus发光灯苹果6荧光灯苹果4.7/5.5LED灯
- LightOJ - 1152 Hiding Gold /poj 3041 二分匹配@
- Google发布了能理解人类语言的云服务
- hdu5546 Ancient Go 简单深搜
- [Go语言]我的第四个Go语言程序
- Bingo和木棍(找不到出处)(优先队列)
- 如何正确使用 Django Forms
- Go语言开发环境IntelliJ IDEA,可惜没有remote debug