खोज…


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 को मॉडल के लिए परिभाषित नहीं किया जाएगा।

फॉरेनके साथ मॉडल

हम इन मॉडलों के साथ काम करेंगे:

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')


Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow