len()
, count()
etc. Assurez-vous de les utiliser au mieux.
# models.py from django.db import models class Sale(models.Model): sold_at = models.DateTimeField( auto_now_add=True, ) charged_amount = models.PositiveIntegerField()
# models.py from django.db import models class Sale(models.Model): sold_at = models.DateTimeField( auto_now_add=True, db_index=True, #DB Indexing ) charged_amount = models.PositiveIntegerField()
# models.py from django.db import models class Sale(models.Model): sold_at = models.DateTimeField( auto_now_add=True, db_index=True, #DB Indexing ) charged_amount = models.PositiveIntegerField() class Meta: indexes = [ ["sold_at", "charged_amount"]]
ip:port
où ip
est l'adresse IP du démon Memcached et port
est le port sur lequel Memcached s'exécute, ou l'URL pointant vers votre instance Redis, en utilisant le schéma approprié.
Pour activer la mise en cache de la base de données avec Memcached, installez pymemcache
à l'aide de pip à l'aide de la commande suivante :
pip install pymemcache
Ensuite, vous pouvez configurer les paramètres de cache dans votre settings.py
comme suit :
CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.memcached.PyMemcacheCache', 'LOCATION': '127.0.0.1:11211', } }
Dans l'exemple ci-dessus, Memcached s'exécute sur le port 11211 de l'hôte local (127.0.0.1), à l'aide de la liaison pymemcache
:
pip install redis
Configurez ensuite les paramètres de cache dans votre settings.py
en ajoutant le code suivant :
CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.redis.RedisCache', 'LOCATION': 'redis://127.0.0.1:6379', } }
Un jeu de requêtes dans Django, généralement, met en cache son résultat lorsque l'évaluation se produit et pour toute opération ultérieure avec ce jeu de requêtes, il vérifie d'abord s'il y a des résultats en cache. Cependant, lorsque vous utilisez iterator()
, il ne vérifie pas le cache et lit les résultats directement à partir de la base de données, ni n'enregistre les résultats dans le jeu de requêtes.
Maintenant, vous devez vous demander comment cela est utile. Considérez un ensemble de requêtes qui renvoie un grand nombre d'objets avec beaucoup de mémoire à mettre en cache mais qui ne doit être utilisé qu'une seule fois, dans ce cas, vous devez utiliser un iterator()
.
queryset = Product.objects.all() for each in queryset: do_something(each)
Alors que si nous utilisons iterator()
, Django maintiendra la connexion SQL ouverte et lira chaque enregistrement, et appellera do_something()
avant de lire l'enregistrement suivant :
queryset = Product.objects.all().iterator() for each in queryset: do_something(each)
Django crée une nouvelle connexion à la base de données pour chaque requête et la ferme une fois la requête terminée. Ce comportement est causé par CONN_MAX_AGE
, qui a une valeur par défaut de 0. Mais combien de temps doit-il être défini ? Cela est déterminé par le volume de trafic sur votre site ; plus le volume est élevé, plus il faut de secondes pour maintenir la connexion. Il est généralement recommandé de commencer avec un petit nombre, tel que 60.
Vous devez encapsuler vos options supplémentaires dans OPTIONS
, comme indiqué dans le
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'dashboard', 'USER': 'root', 'PASSWORD': 'root', 'HOST': '127.0.0.1', 'PORT': '3306', 'OPTIONS': { 'CONN_MAX_AGE': '60', } } }
Remarque : Ces expressions sont définies dans django.db.models.expressions
et django.db.models.aggregates
, mais pour plus de commodité, elles sont disponibles et généralement importées de django.db.models
.
Dans l'API Django Queryset, les expressions F()
sont utilisées pour faire directement référence aux valeurs des champs du modèle. Il vous permet de vous référer aux valeurs de champ du modèle et d'effectuer des actions de base de données sur celles-ci sans avoir à les extraire de la base de données et dans la mémoire Python. Au lieu de cela, Django utilise l'objet F()
pour produire une phrase SQL qui définit l'activité de base de données nécessaire.
products = Product.objects.all() for product in products: product.price *= 1.2 product.save()
Cependant, si nous utilisons F()
, nous pouvons le faire en une seule requête comme suit :
from django.db.models import F Product.objects.update(price=F('price') * 1.2)
select_related()
et prefetch_related()
Django fournit select_related()
et prefetch_related()
pour optimiser vos ensembles de requêtes en minimisant le nombre de requêtes de base de données.
select_related()
"suit" les relations de clé étrangère, en sélectionnant des données d'objets connexes supplémentaires lorsqu'il exécute sa requête.
prefetch_related()
effectue une recherche distincte pour chaque relation et effectue la « jonction » en Python.
select_related()
Nous utilisons select_related()
lorsque l'élément à sélectionner est un objet unique, ce qui signifie un ForeignKey
avant, OneToOne
et un champ OneToOne
arrière.
Vous pouvez utiliser select_related()
pour créer une seule requête qui renvoie tous les objets liés pour une seule instance pour les connexions un-plusieurs et un-à-un. Lorsque la requête est exécutée, select_related()
récupère toutes les données d'objets connexes supplémentaires à partir des relations de clé étrangère.
select_related()
fonctionne en générant une jointure SQL et inclut les colonnes de l'objet associé dans l'expression SELECT
. Par conséquent, select_related()
renvoie les éléments associés dans la même requête de base de données.
Bien que select_related()
produise une requête plus sophistiquée, les données acquises sont mises en cache, ainsi la gestion des données obtenues ne nécessite aucune demande de base de données supplémentaire.
queryset = Tweet.objects.select_related('owner').all()
prefetch_related()
En revanche, prefetch_related()
est utilisé pour les connexions plusieurs à plusieurs et plusieurs à un. Il produit une seule requête qui inclut tous les modèles et les filtres sont donnés dans la requête.
Book.objects.prefetch_related('author').get(id=1).author.first_name
Découvrez la différence entre select_related()
et prefetch_related()
en détail .
bulk_create()
et bulk_update()
bulk_create()
est une méthode qui crée la liste d'objets fournie dans la base de données avec une seule requête. De même, bulk_update()
est une méthode qui met à jour les champs donnés sur les instances de modèle fournies avec une seule requête.
class Post(models.Model): title = models.CharField(max_length=300, unique=True) time = models.DateTimeField(auto_now_add=True) def __str__(self): return self.title
Maintenant, disons que nous voulons ajouter plusieurs enregistrements de données à ce modèle, nous pouvons alors utiliser bulk_create()
comme ceci :
#articles articles = [Post(title="Hello python"), Post(title="Hello django"), Post(title="Hello bulk")] #insert data Post.objects.bulk_create(articles)
>>> Post.objects.all() <QuerySet [<Post: Hello python>, <Post: Hello django>, <Post: Hello bulk>]>
Et si nous voulons mettre à jour les données, nous pouvons utiliser bulk_update()
comme ceci :
update_queries = [] a = Post.objects.get(id=14) b = Post.objects.get(id=15) c = Post.objects.get(id=16) #set update value a.title="Hello python updated" b.title="Hello django updated" c.title="Hello bulk updated" #append update_queries.extend((a, b, c)) Post.objects.bulk_update(update_queries, ['title'])
>>> Post.objects.all() <QuerySet [<Post: Hello python updated>, <Post: Hello django updated>, <Post: Hello bulk updated>]>