django模型查询
I like Django. It’s a well-considered and intuitive framework with a name I can pronounce out loud. You can use it to quickly spin up a weekend-sized project, and you can also use it to run full-blown production applications at scale.
我喜欢Django。 这是一个经过深思熟虑的直观框架,其名称我可以大声念出来。 您可以使用它快速启动一个周末大小的项目 ,也可以使用它大规模运行成熟的生产应用程序 。
I’ve done both of these things, and over the years I’ve discovered how to use some of Django’s features for maximum efficiency. These are:
我已经完成了这两项工作,并且多年来,我发现了如何使用Django的某些功能来最大程度地提高效率。 这些是:
Let’s look at how these tools let you create a performant Django application that’s pleasant to build and maintain.
让我们看一下这些工具如何使您创建一个性能良好的Django应用程序,该应用程序易于构建和维护。
Remember that Django is all Python under the hood. When it comes to views, you’ve got two choices: view functions (sometimes called “function-based views”), or class-based views.
请记住,Django就是所有的Python。 关于视图,您有两种选择: 视图函数 (有时称为“基于函数的视图”)或基于类的视图 。
Years ago when I first built ApplyByAPI, it was initially composed entirely of function-based views. These offer granular control, and are good for implementing complex logic. Just as in a Python function, you have complete control (for better or worse) over what the view does.
多年前,当我第一次构建ApplyByAPI时 ,它最初完全由基于函数的视图组成。 这些提供细粒度的控制,非常适合实现复杂的逻辑。 就像在Python函数中一样,您可以完全控制视图的功能(好坏)。
But with great control comes great responsibility, and function-based views can be a little tedious to use. You’re responsible for writing all the necessary methods for the view to work - this is what allows you to completely tailor your application.
但是,如果控制力强,责任就大了,基于功能的视图使用起来可能会有些乏味。 您负责编写所有必要的方法以使视图正常工作-这就是您可以完全定制应用程序的原因。
In the case of ApplyByAPI, there were only a sparse few places where that level of tailored functionality was really necessary. Everywhere else, function-based views began making my life harder. Writing what is essentially a custom view for run-of-the-mill operations like displaying data on a list page became tedious, repetitive, and error-prone.
就ApplyByAPI而言,只有很少的地方真正需要这种量身定制的功能。 在其他任何地方,基于函数的视图都使我的生活更加艰难。 编写本质上是针对常规操作(例如在列表页面上显示数据)的自定义视图的过程变得乏味,重复且容易出错。
With function-based views, you’ll need figure out which Django methods to implement in order to handle requests and pass data to views. Unit testing can take some work to write. In short, the granular control that function-based views offer also requires some granular tedium to properly implement.
使用基于函数的视图,您将需要弄清楚要实现哪些Django方法,以便处理请求并将数据传递给视图。 单元测试可能需要一些工作来编写。 简而言之,基于函数的视图提供的粒度控制还需要一些粒度繁琐的代码才能正确实现。
I ended up holding back ApplyByAPI while I refactored the majority of the views into class-based views. This was not a small amount of work and refactoring, but when it was done, I had a bunch of tiny views that made a huge difference. I mean, just look at this one:
我最终阻止了ApplyByAPI,同时将大多数视图重构为基于类的视图。 这不是一件小小的工作和重构,但是当完成时,我有一堆微小的视图,它们产生了很大的变化。 我的意思是,只看这一个:
class ApplicationsList(ListView):
model = Application
template_name = "applications.html"
It’s three lines. My developer ergonomics, and my life, got a lot easier.
三行。 开发人员的人机工程学以及我的生活变得轻松了很多。
You may think of class-based views as templates that cover most of the functionality any app needs. There are views for displaying lists of things, for viewing a thing in detail, and editing views for performing CRUD (Create, Read, Update, Delete) operations.
您可能会将基于类的视图视为涵盖任何应用程序所需大多数功能的模板。 有用于显示事物列表,用于详细查看事物以及编辑视图以执行CRUD(创建,读取,更新,删除)操作的视图 。
Because implementing one of these generic views takes only a few lines of code, my application logic became dramatically succinct. This gave me less repeated code, fewer places for something to go wrong, and a more manageable application in general.
因为实现这些通用视图之一仅需要几行代码,所以我的应用程序逻辑变得非常简洁。 这使我减少了重复的代码,减少了出错地方,并且使应用程序更容易管理。
Class-based views are fast to implement and use. The built-in class-based generic views may require less work to test, since you don’t need to write tests for the base view Django provides. (Django does its own tests for that; no need for your app to double-check.)
基于类的视图可以快速实现和使用。 内置的基于类的通用视图可能需要较少的测试工作,因为您无需为Django提供的基本视图编写测试。 (Django为此进行了自己的测试;您的应用无需再次检查。)
To tweak a generic view to your needs, you can subclass a generic view and override attributes or methods. In my case, since I only needed to write tests for any customizations I added, my test files became dramatically shorter, as did the time and resources it took to run them.
要根据需要调整通用视图,可以将通用视图子类化,并覆盖属性或方法。 就我而言,由于我只需要为添加的所有自定义编写测试,因此我的测试文件大大缩短了,运行它们所需的时间和资源也大大减少了。
When you’re weighing the choice between function-based or class-based views, consider the amount of customization the view needs, and the future work that will be necessary to test and maintain it.
在权衡基于函数的视图或基于类的视图之间的选择时,请考虑该视图所需的定制量以及测试和维护该视图所需的未来工作。
If the logic is common, you may be able to hit the ground running with a generic class-based view. If you need sufficient granularity that re-writing a base view’s methods would make it overly complicated, consider a function-based view instead.
如果逻辑是通用的,那么您可以使用基于类的通用视图开始工作。 如果您需要足够的粒度来重写基本视图的方法将使其变得过于复杂,请考虑使用基于函数的视图。
Models organize your Django application’s central concepts to help make them flexible, robust, and easy to work with. If used wisely, models are a powerful way to collate your data into a definitive source of truth.
模型组织了Django应用程序的中心概念,以帮助它们变得灵活,健壮且易于使用。 如果使用得当,模型是将数据整理成确定的真实来源的有效方法。
Like views, Django provides some built-in model types for the convenience of implementing basic authentication, including the User and Permission models. For everything else, you can create a model that reflects your concept by inheriting from a parent Model class.
像视图一样,Django提供了一些内置模型类型以方便实现基本身份验证,包括用户模型和权限模型。 对于其他所有内容,您可以通过从父Model类继承来创建反映您的概念的模型 。
class StaffMember(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
company = models.OneToOneField(Company, on_delete=models.CASCADE)
def __str__(self):
return self.company.name + " - " + self.user.email
When you create a custom model in Django, you subclass Django’s Model class and take advantage of all its power. Each model you create generally maps to a database table. Each attribute is a database field. This gives you the ability to create objects to work with that humans can better understand.
在Django中创建自定义模型时,您可以将Django的Model类作为子类,并利用其所有功能。 您创建的每个模型通常都映射到数据库表。 每个属性都是一个数据库字段。 这使您能够创建人类可以更好理解的对象。
You can make a model useful to you by defining its fields. Many built-in field types are conveniently provided. These help Django figure out the data type, the HTML widget to use when rendering a form, and even form validation requirements. If you need to, you can write custom model fields.
您可以通过定义模型字段使模型对您有用。 提供了许多内置字段类型 。 这些帮助Django找出数据类型,呈现表单时要使用HTML 小部件 ,甚至表单验证要求。 如果需要,您可以编写自定义模型字段 。
Database relationships can be defined using a ForeignKey field (many-to-one), or a ManyToManyField (give you three guesses). If those don’t suffice, there’s also a OneToOneField.
可以使用ForeignKey字段(多对一)或ManyToManyField (给您三个猜测)来定义数据库关系 。 如果这些还不够的话,还有一个OneToOneField 。
Together, these allow you to define relations between your models with levels of complexity limited only by your imagination. (Depending on the imagination you have, this may or may not be an advantage.)
在一起,它们使您可以定义模型之间的关系,其复杂程度仅受您的想象力限制。 (根据您的想象力,这可能是优势,也可能不是优势。)
Use your model’s Manager (objects
by default) to construct a QuerySet. This is a representation of objects in your database that you can refine, using methods, to retrieve specific subsets. All available methods are in the QuerySet API and can be chained together for even more fun.
使用模型的Manager(默认为objects
)来构造QuerySet 。 这是数据库中对象的一种表示形式,您可以使用方法优化这些对象以检索特定的子集。 所有可用的方法都在QuerySet API中 ,可以将它们链接在一起以获得更多的乐趣。
Post.objects.filter(
type="new"
).exclude(
title__startswith="Blockchain"
)
Some methods return new QuerySets, such as filter()
, or exclude()
. Chaining these can give you powerful queries without affecting performance, as QuerySets aren’t fetched from the database until they are evaluated. Methods that evaluate a QuerySet include get()
, count()
, len()
, list()
, or bool()
.
一些方法返回新的QuerySet,例如filter()
或exclude()
。 链接这些可以在不影响性能的情况下为您提供强大的查询,因为只有在对QuerySet 求值后才从数据库中获取QuerySet。 评估QuerySet的方法包括get()
, count()
, len()
, list()
或bool()
。
Iterating over a QuerySet also evaluates it, so avoid doing so where possible to improve query performance. For instance, if you just want to know if an object is present, you can use exists()
to avoid iterating over database objects.
遍历QuerySet也会对其进行评估,因此请尽可能避免这样做,以提高查询性能。 例如,如果您只想知道对象是否存在,则可以使用exists()
避免迭代数据库对象。
Use get()
in cases where you want to retrieve a specific object. This method raises MultipleObjectsReturned
if something unexpected happens, as well as the DoesNotExist
exception, if, take a guess.
如果要检索特定对象,请使用get()
。 如果发生意外,则此方法将引发MultipleObjectsReturned
如果引发猜测,则将DoesNotExist
异常。
If you’d like to get an object that may not exist in the context of a user’s request, use the convenient get_object_or_404()
or get_list_or_404()
which raises Http404
instead of DoesNotExist
. These helpful shortcuts are suited to just this purpose. To create an object that doesn’t exist, there’s also the convenient get_or_create()
.
如果要获取在用户请求的上下文中可能不存在的对象,请使用便捷的get_object_or_404()
或get_list_or_404()
,它引发Http404
而不是DoesNotExist
。 这些有用的快捷方式仅适用于此目的。 要创建一个不存在的对象,还可以使用便捷的get_or_create()
。
You’ve now got a handle on these three essential tools for building your efficient Django application – congratulations!
现在,您已经掌握了这三个用于构建高效Django应用程序的基本工具的方法-恭喜!
There’s a lot more that Django can do for you, so stay tuned for future articles.
Django可以为您做更多的工作,请继续关注以后的文章。
If you’re going to build on GitHub, you may like to set up my django-security-check GitHub Action. In the meantime, you’re well on your way to building a beautiful software project.
如果要在GitHub上构建,则可能要设置django-security-check GitHub Action 。 同时,您正在顺利地构建漂亮的软件项目。
翻译自: https://www.freecodecamp.org/news/how-to-write-efficient-views-models-and-queries-in-django/
django模型查询