Django
कस्टम प्रबंधक और क्वेरी
खोज…
Querysets और `as_manager` विधि का उपयोग करके एक मूल प्रबंधक को परिभाषित करना
Django manger एक इंटरफ़ेस है जिसके माध्यम से django मॉडल डेटाबेस पर सवाल उठाता है। अधिकांश django क्वेरीज़ में उपयोग की जाने वाली objects
फ़ील्ड वास्तव में django द्वारा बनाई गई डिफ़ॉल्ट प्रबंधक है (यह केवल तभी बनाया जाता है जब हम कस्टम प्रबंधकों को परिभाषित नहीं करते हैं)।
हम कस्टम मैनेजर / क्वेरीसेट को क्यों परिभाषित करेंगे?
हमारे कोडबेस पर सामान्य प्रश्नों को लिखने से बचने के लिए और इसके बजाय उन्हें अमूर्तता को याद रखने के लिए आसान का उपयोग करके देखें। उदाहरण: अपने लिए तय करें कि कौन सा संस्करण अधिक पठनीय है:
- केवल सभी सक्रिय उपयोगकर्ता प्राप्त करें:
User.objects.filter(is_active=True)
बनामUser.manager.active()
- हमारे फलक पर सभी सक्रिय त्वचा विशेषज्ञ प्राप्त करें:
User.objects.filter(is_active=True).filter(is_doctor=True).filter(specialization='Dermatology')
बनामUser.manager.doctors.with_specialization('Dermatology')
एक और लाभ यह है कि अगर कल हम सभी psychologists
को भी तय करते हैं कि हम dermatologists
, तो हम आसानी से अपने प्रबंधक में क्वेरी को संशोधित कर सकते हैं और इसके साथ किया जा सकता है।
नीचे एक QuerySet
Manager
बनाने और as_manager
विधि का उपयोग करके परिभाषित कस्टम Manager
बनाने का एक उदाहरण है।
from django.db.models.query import QuerySet
class ProfileQuerySet(QuerySet):
def doctors(self):
return self.filter(user_type="Doctor", user__is_active=True)
def with_specializations(self, specialization):
return self.filter(specializations=specialization)
def users(self):
return self.filter(user_type="Customer", user__is_active=True)
ProfileManager = ProfileQuerySet.as_manager
हम इसे अपने मॉडल में नीचे जोड़ देंगे:
class Profile(models.Model):
...
manager = ProfileManager()
नोट : एक बार जब हमने अपने मॉडल पर एक manager
को परिभाषित कर लिया है, तो objects
को मॉडल के लिए परिभाषित नहीं किया जाएगा।
सभी प्रश्नों के लिए select_related है
फॉरेनके साथ मॉडल
हम इन मॉडलों के साथ काम करेंगे:
from django.db import models
class Book(models.Model):
name= models.CharField(max_length=50)
author = models.ForeignKey(Author)
class Author(models.Model):
name = models.CharField(max_length=50)
मान लीजिए हम अक्सर (हमेशा) book.author.name
तक book.author.name
दृश्य में
हम निम्न का उपयोग कर सकते हैं, हर बार,
books = Book.objects.select_related('author').all()
लेकिन यह DRY नहीं है।
कस्टम प्रबंधक
class BookManager(models.Manager):
def get_queryset(self):
qs = super().get_queryset()
return qs.select_related('author')
class Book(models.Model):
...
objects = BookManager()
नोट : super
को कॉल अजगर 2.x के लिए बदलना चाहिए
अब हमें केवल विचारों में उपयोग करना है
books = Book.objects.all()
और टेम्पलेट / दृश्य में कोई अतिरिक्त प्रश्न नहीं किया जाएगा।
कस्टम प्रबंधकों को परिभाषित करें
बहुत बार यह उन मॉडलों से निपटने के लिए होता है जिनके पास published
फ़ील्ड की तरह कुछ होता है। वस्तुओं को पुनर्प्राप्त करते समय इस तरह के क्षेत्र लगभग हमेशा उपयोग किए जाते हैं, ताकि आप खुद को कुछ लिखने के लिए पाएं:
my_news = News.objects.filter(published=True)
कई बार। आप इन स्थितियों से निपटने के लिए कस्टम प्रबंधकों का उपयोग कर सकते हैं, ताकि आप तब कुछ लिख सकें:
my_news = News.objects.published()
जो कि अन्य डेवलपर्स द्वारा पढ़ने के लिए अच्छे और अधिक आसान है।
अपनी ऐप डायरेक्टरी में एक फ़ाइल managers.py
बनाएँ, और एक नया models.Manager
परिभाषित करें। models.Manager
क्लास:
from django.db import models
class NewsManager(models.Manager):
def published(self, **kwargs):
# the method accepts **kwargs, so that it is possible to filter
# published news
# i.e: News.objects.published(insertion_date__gte=datetime.now)
return self.filter(published=True, **kwargs)
मॉडल वर्ग में objects
संपत्ति को फिर से परिभाषित करके इस वर्ग का उपयोग करें:
from django.db import models
# import the created manager
from .managers import NewsManager
class News(models.Model):
""" News model
"""
insertion_date = models.DateTimeField('insertion date', auto_now_add=True)
title = models.CharField('title', max_length=255)
# some other fields here
published = models.BooleanField('published')
# assign the manager class to the objects property
objects = NewsManager()
अब आप अपनी प्रकाशित खबर को इस प्रकार प्राप्त कर सकते हैं:
my_news = News.objects.published()
और आप अधिक फ़िल्टरिंग भी कर सकते हैं:
my_news = News.objects.published(title__icontains='meow')