Django 2.1 - Customizing authentication in Django

Django में प्रमाणीकरण का अनुकूलन




django

Django में प्रमाणीकरण का अनुकूलन

Django के साथ आने वाला प्रमाणीकरण अधिकांश सामान्य मामलों के लिए पर्याप्त है, लेकिन आपको आउट-ऑफ-द-बॉक्स डिफॉल्ट्स से मिलने की आवश्यकता नहीं हो सकती है। आपकी परियोजनाओं में प्रमाणीकरण को अनुकूलित करने के लिए यह समझना आवश्यक है कि प्रदान की गई प्रणाली के कौन से बिंदु एक्स्टेंसिबल या बदली हैं यह दस्तावेज़ इस बारे में विवरण प्रदान करता है कि ऑर्ट सिस्टम को कैसे अनुकूलित किया जा सकता है।

प्रमाणीकरण बैकएंड के लिए एक एक्स्टेंसिबल सिस्टम प्रदान करता है जब उपयोगकर्ता मॉडल के साथ संग्रहीत उपयोगकर्ता नाम और पासवर्ड को Django के डिफ़ॉल्ट से अलग सेवा के खिलाफ प्रमाणित करने की आवश्यकता होती है।

आप अपने मॉडल कस्टम अनुमतियाँ दे सकते हैं जिन्हें Django के प्राधिकरण सिस्टम के माध्यम से जांचा जा सकता है।

आप डिफ़ॉल्ट User मॉडल का extend कर सकते extend , या पूरी तरह से अनुकूलित मॉडल का substitute

अन्य प्रमाणीकरण स्रोत

कई बार आपको किसी अन्य प्रमाणीकरण स्रोत में हुक करने की आवश्यकता हो सकती है - अर्थात, उपयोगकर्ता नाम और पासवर्ड या प्रमाणीकरण विधियों का एक अन्य स्रोत।

उदाहरण के लिए, आपकी कंपनी में पहले से ही एक LDAP सेटअप हो सकता है जो हर कर्मचारी के लिए एक उपयोगकर्ता नाम और पासवर्ड संग्रहीत करता है। यदि उपयोगकर्ता LDAP और Django- आधारित अनुप्रयोगों में अलग-अलग खाते थे, तो यह नेटवर्क व्यवस्थापक और स्वयं उपयोगकर्ताओं दोनों के लिए एक परेशानी होगी।

तो, इस तरह की स्थितियों को संभालने के लिए, Django प्रमाणीकरण प्रणाली आपको अन्य प्रमाणीकरण स्रोतों में प्लग करने देती है। आप Django के डिफ़ॉल्ट डेटाबेस-आधारित योजना को ओवरराइड कर सकते हैं, या आप अन्य सिस्टम के साथ मिलकर डिफ़ॉल्ट सिस्टम का उपयोग कर सकते हैं।

Django के साथ शामिल प्रमाणीकरण बैकेंड की जानकारी के लिए प्रमाणीकरण बैकएंड संदर्भ देखें।

प्रमाणीकरण बैकएंड निर्दिष्ट करता है

पर्दे के पीछे, Django "प्रमाणीकरण बैकेंड" की एक सूची रखता है जो इसे प्रमाणीकरण के लिए जांचता है। जब कोई django.contrib.auth.authenticate() कॉल करता है - जैसा कि उपयोगकर्ता को लॉग इन करने के तरीके में वर्णित है - Django अपने सभी प्रमाणीकरण बैकेंड को प्रमाणित करने का प्रयास करता है। यदि पहली प्रमाणीकरण विधि विफल हो जाती है, तो Django दूसरा प्रयास करता है, और इसी तरह, जब तक कि सभी बैकेंड का प्रयास नहीं किया गया हो।

प्रमाणीकरण की सूची का उपयोग करने की सूची AUTHENTICATION_BACKENDS सेटिंग में निर्दिष्ट है। यह पायथन पथ नामों की एक सूची होनी चाहिए जो पायथन वर्गों को इंगित करती है जो प्रमाणित करना जानते हैं। ये कक्षाएं आपके पाइथन पथ पर कहीं भी हो सकती हैं।

डिफ़ॉल्ट रूप से, AUTHENTICATION_BACKENDS लिए सेट है:

['django.contrib.auth.backends.ModelBackend']

यह मूलभूत प्रमाणीकरण बैकएंड है जो Django उपयोगकर्ता डेटाबेस की जांच करता है और अंतर्निहित अनुमतियों पर सवाल उठाता है। यह किसी भी दर सीमित तंत्र के माध्यम से जानवर बल के हमलों के खिलाफ सुरक्षा प्रदान नहीं करता है। आप कस्टम रेट बैकएंड में या तो अपनी स्वयं की दर सीमित करने वाली प्रणाली को लागू कर सकते हैं, या अधिकांश वेब सर्वरों द्वारा प्रदान किए गए तंत्र का उपयोग कर सकते हैं।

AUTHENTICATION_BACKENDS का क्रम मायने रखता है, इसलिए यदि एक ही उपयोगकर्ता नाम और पासवर्ड कई बैकेंड में मान्य है, तो Django पहले सकारात्मक मैच में प्रसंस्करण बंद कर देगा।

यदि कोई बैकएंड PermissionDenied अपवाद को उठाता है, तो प्रमाणीकरण तुरंत विफल हो जाएगा। Django अनुसरण करने वाले बैकेंड की जाँच नहीं करेगा।

ध्यान दें

एक उपयोगकर्ता द्वारा प्रमाणित हो जाने के बाद, Django स्टोर जो बैकेंड को उपयोगकर्ता के सत्र में उपयोगकर्ता को प्रमाणित करने के लिए उपयोग किया गया था, और जब भी वर्तमान में प्रमाणित उपयोगकर्ता तक पहुंच की आवश्यकता होती है, तो उस सत्र की अवधि के लिए उसी बैकएंड का उपयोग करता है। इसका प्रभावी रूप से अर्थ है कि प्रमाणीकरण स्रोत प्रति-सत्र के आधार पर कैश किए जाते हैं, इसलिए यदि आप AUTHENTICATION_BACKENDS बदलते हैं, तो आपको सत्र डेटा साफ़ करने की आवश्यकता होगी यदि आपको उपयोगकर्ताओं को अलग-अलग तरीकों का उपयोग करके पुन: प्रमाणित करने के लिए बाध्य करने की आवश्यकता है। ऐसा करने का एक सरल तरीका यह है कि आप Session.objects.all().delete()

एक प्रमाणीकरण बैकेंड लिखना

प्रमाणीकरण बैकएंड एक ऐसा वर्ग है जो दो आवश्यक विधियों को लागू करता है: get_user(user_id) और authenticate(request, **credentials) , साथ ही वैकल्पिक अनुमति संबंधित प्राधिकरण विधियों का एक सेट।

get_user विधि एक user_id लेती है - जो एक उपयोगकर्ता नाम, डेटाबेस आईडी या जो कुछ भी हो सकता है, लेकिन आपके उपयोगकर्ता ऑब्जेक्ट की प्राथमिक कुंजी होनी चाहिए - और उपयोगकर्ता ऑब्जेक्ट लौटाता है।

authenticate विधि खोजशब्द तर्क के रूप में एक request तर्क और प्रमाणिकता लेती है। ज्यादातर समय, यह सिर्फ इस तरह दिखेगा:

class MyBackend:
    def authenticate(self, request, username=None, password=None):
        # Check the username/password and return a user.
        ...

लेकिन यह एक टोकन को भी प्रमाणित कर सकता है, जैसे:

class MyBackend:
    def authenticate(self, request, token=None):
        # Check the token and return a user.
        ...

किसी भी तरह से, authenticate() को प्राप्त होने वाले क्रेडेंशियल की जांच करनी चाहिए और एक उपयोगकर्ता ऑब्जेक्ट को वापस करना चाहिए जो क्रेडेंशियल मान्य होने पर उन क्रेडेंशियल्स से मेल खाता है। यदि वे वैध नहीं हैं, तो इसे वापस None लौटना चाहिए।

request एक HttpRequest और ऐसा None हो सकता है यदि इसे django.contrib.auth.authenticate() करने के लिए प्रदान नहीं किया गया था django.contrib.auth.authenticate() (जो इसे बैकएंड पर पास करता है)।

Django व्यवस्थापक कसकर Django उपयोगकर्ता ऑब्जेक्ट के लिए युग्मित है। इससे निपटने का सबसे अच्छा तरीका प्रत्येक उपयोगकर्ता के लिए एक Django User ऑब्जेक्ट बनाना है जो आपके बैकएंड के लिए मौजूद है (जैसे, आपके LDAP निर्देशिका में, आपके बाहरी SQL डेटाबेस, आदि) आप या तो अग्रिम में ऐसा करने के लिए एक स्क्रिप्ट लिख सकते हैं, या आपका authenticate तरीका उपयोगकर्ता द्वारा लॉग इन करने पर पहली बार कर सकता है।

यहां एक उदाहरण बैकएंड है जो आपकी settings.py में परिभाषित उपयोगकर्ता नाम और पासवर्ड चर के खिलाफ प्रमाणित करता है और एक User द्वारा पहली बार एक Django User ऑब्जेक्ट बनाता है।

from django.conf import settings
from django.contrib.auth.hashers import check_password
from django.contrib.auth.models import User

class SettingsBackend:
    """
    Authenticate against the settings ADMIN_LOGIN and ADMIN_PASSWORD.

    Use the login name and a hash of the password. For example:

    ADMIN_LOGIN = 'admin'
    ADMIN_PASSWORD = 'pbkdf2_sha256$30000$Vo0VlMnkR4Bk$qEvtdyZRWTcOsCnI/oQ7fVOu1XAURIZYoOZ3iq8Dr4M='
    """

    def authenticate(self, request, username=None, password=None):
        login_valid = (settings.ADMIN_LOGIN == username)
        pwd_valid = check_password(password, settings.ADMIN_PASSWORD)
        if login_valid and pwd_valid:
            try:
                user = User.objects.get(username=username)
            except User.DoesNotExist:
                # Create a new user. There's no need to set a password
                # because only the password from settings.py is checked.
                user = User(username=username)
                user.is_staff = True
                user.is_superuser = True
                user.save()
            return user
        return None

    def get_user(self, user_id):
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None

कस्टम बैकएंड में प्राधिकरण को संभालना

कस्टम विशेषाधिकार बैकएंड अपनी अनुमति प्रदान कर सकते हैं।

उपयोगकर्ता मॉडल किसी भी प्रमाणीकरण बैकएंड को इन कार्यों को लागू करने के लिए अनुमति देखने के कार्यों ( get_group_permissions() , get_all_permissions() , has_perm() , और has_module_perms() ) को has_module_perms()

उपयोगकर्ता को दी गई अनुमति सभी बैकएंड द्वारा लौटाए गए सभी अनुमतियों का सुपरसेट होगा। यही है, Django एक उपयोगकर्ता को एक अनुमति देता है कि कोई भी बैकेंड अनुदान देता है।

यदि एक बैकएंड has_perm() या has_module_perms() में PermissionDenied अपवाद को has_perm() , तो प्राधिकरण तुरंत विफल हो जाएगा और Django अनुसरण करने वाले बैकेंड की जांच नहीं करेगा।

ऊपर दिए गए सरल बैकएंड मैजिक एडमिन के लिए अनुमतियों को काफी सरलता से लागू कर सकते हैं:

class SettingsBackend:
    ...
    def has_perm(self, user_obj, perm, obj=None):
        return user_obj.username == settings.ADMIN_LOGIN

यह उपर्युक्त उदाहरण में उपयोगकर्ता को दी गई अनुमति के लिए पूर्ण अनुमति देता है। ध्यान दें कि संबंधित django.contrib.auth.models.User फ़ंक्शंस में दिए गए एक ही तर्कों के अलावा, बैकेंड के कार्य सभी उपयोगकर्ता ऑब्जेक्ट लेते हैं, जो एक तर्क के रूप में एक अनाम उपयोगकर्ता हो सकता है।

एक पूर्ण प्राधिकरण कार्यान्वयन ModelBackend क्लास में django/contrib/auth/backends.py ModelBackend django/contrib/auth/backends.py ModelBackend में पाया जा सकता है, जो कि डिफ़ॉल्ट बैकएंड है और सबसे अधिक समय के लिए auth_permission टेबल पर सवाल auth_permission । यदि आप बैकएंड एपीआई के केवल भाग के लिए कस्टम व्यवहार प्रदान करना चाहते हैं, तो आप कस्टम बैकएंड में पूर्ण एपीआई को लागू करने के बजाय पायथन इनहेरिटेंस और ModelBackend का लाभ उठा सकते हैं।

अनाम उपयोगकर्ताओं के लिए प्राधिकरण

एक अनाम उपयोगकर्ता वह है जो प्रमाणित नहीं है अर्थात उन्होंने कोई मान्य प्रमाणीकरण विवरण प्रदान नहीं किया है। हालांकि, इसका मतलब यह नहीं है कि वे कुछ भी करने के लिए अधिकृत नहीं हैं। सबसे बुनियादी स्तर पर, अधिकांश वेबसाइट गुमनाम उपयोगकर्ताओं को साइट के अधिकांश ब्राउज़ करने के लिए अधिकृत करती हैं, और कई अनाम पोस्टिंग आदि की अनुमति देते हैं।

Django के अनुमति ढांचे में अनाम उपयोगकर्ताओं के लिए अनुमतियों को संग्रहीत करने के लिए जगह नहीं है। हालाँकि, प्रमाणीकरण बैकएंड के लिए पारित उपयोगकर्ता ऑब्जेक्ट एक django.contrib.auth.models.AnonymousUser ऑब्जेक्ट हो सकता है, बैकएंड को अनाम उपयोगकर्ताओं के लिए कस्टम प्राधिकरण व्यवहार निर्दिष्ट करने की अनुमति देता है। यह पुन: उपयोग करने योग्य ऐप्स के लेखकों के लिए विशेष रूप से उपयोगी है, जो अनाम पहुँच को नियंत्रित करने के लिए, सेटिंग्स की आवश्यकता के बजाय, सामान्य बैकएंड पर प्राधिकरण के सभी प्रश्नों को निर्दिष्ट कर सकते हैं।

निष्क्रिय उपयोगकर्ताओं के लिए प्राधिकरण

एक निष्क्रिय उपयोगकर्ता वह है जो अपने is_active क्षेत्र को False सेट करता है। ModelBackend और RemoteUserBackend प्रमाणीकरण बैकेंड इन उपयोगकर्ताओं को प्रमाणीकरण से प्रतिबंधित करता है। यदि किसी कस्टम उपयोगकर्ता मॉडल में is_active फ़ील्ड नहीं है, तो सभी उपयोगकर्ताओं को प्रमाणित करने की अनुमति दी जाएगी।

यदि आप निष्क्रिय उपयोगकर्ताओं को प्रमाणित करने की अनुमति देना चाहते हैं, तो आप AllowAllUsersModelBackend या AllowAllUsersRemoteUserBackend उपयोग कर सकते हैं।

अनुमति प्रणाली में अनाम उपयोगकर्ताओं का समर्थन एक परिदृश्य के लिए अनुमति देता है जहां अनाम उपयोगकर्ताओं के पास कुछ करने की अनुमति होती है जबकि निष्क्रिय प्रमाणित उपयोगकर्ता नहीं करते हैं।

अपने स्वयं के बैकएंड अनुमति विधियों में उपयोगकर्ता के is_active विशेषता के लिए परीक्षण करना न भूलें।

ऑब्जेक्ट अनुमतियां संभालना

Django के अनुमति ढांचे में ऑब्जेक्ट अनुमतियों के लिए एक आधार है, हालांकि कोर में इसके लिए कोई कार्यान्वयन नहीं है। इसका मतलब है कि ऑब्जेक्ट अनुमतियों के लिए जाँच करने से हमेशा False या एक खाली सूची (प्रदर्शन किए गए चेक के आधार पर) वापस आ जाएगी। प्रमाणीकरण बैकएंड प्रत्येक ऑब्जेक्ट संबंधित प्राधिकरण पद्धति के लिए कीवर्ड पैरामीटर obj और user_obj प्राप्त करेगा और ऑब्जेक्ट स्तर की अनुमति को उचित रूप में वापस कर सकता है।

कस्टम अनुमतियाँ

किसी दिए गए मॉडल ऑब्जेक्ट के लिए कस्टम अनुमतियाँ बनाने के लिए, permissions मॉडल मेटा विशेषता का उपयोग करें।

यह उदाहरण टास्क मॉडल तीन कस्टम अनुमतियाँ बनाता है, अर्थात, उपयोगकर्ता जो कार्य कर सकते हैं या टास्क उदाहरणों के साथ नहीं कर सकते हैं, आपके आवेदन के लिए विशिष्ट:

class Task(models.Model):
    ...
    class Meta:
        permissions = (
            ("view_task", "Can see available tasks"),
            ("change_task_status", "Can change the status of tasks"),
            ("close_task", "Can remove a task by setting its status as closed"),
        )

केवल एक ही चीज़ यह करती है कि जब आप post_migrate करते हैं तो उन अतिरिक्त अनुमतियों का निर्माण हो जाता है, जब आप manage.py migrate (फ़ंक्शन जो अनुमतियाँ बनाता है, post_migrate सिग्नल से जुड़ा है)। आपका कोड इन अनुमतियों के मूल्य की जांच करने का प्रभारी है जब कोई उपयोगकर्ता एप्लिकेशन द्वारा प्रदान की गई कार्यक्षमता (कार्यों को देखने, कार्यों की स्थिति बदलने, कार्यों को बंद करने) को एक्सेस करने की कोशिश कर रहा है। उपरोक्त उदाहरण जारी रखते हुए, यदि उपयोगकर्ता है तो निम्न चेक। कार्य देख सकते हैं:

user.has_perm('app.view_task')

मौजूदा User मॉडल का विस्तार

अपने स्वयं के मॉडल को प्रतिस्थापित किए बिना डिफ़ॉल्ट django.contrib.auth.models.User मॉडल का विस्तार करने के दो तरीके हैं। यदि आपको जिन परिवर्तनों की आवश्यकता है, वे विशुद्ध रूप से व्यवहारिक हैं, और डेटाबेस में संग्रहीत किसी भी परिवर्तन की आवश्यकता नहीं है, तो आप django.contrib.auth.models.User आधार पर एक प्रॉक्सी मॉडल बना सकते हैं। यह डिफ़ॉल्ट ऑर्डर, कस्टम मैनेजर, या कस्टम मॉडल विधियों सहित प्रॉक्सी मॉडल द्वारा दी जाने वाली किसी भी सुविधा के लिए अनुमति देता है।

यदि आप User से संबंधित जानकारी संग्रहीत करना चाहते हैं, तो आप अतिरिक्त जानकारी के लिए फ़ील्ड वाले OneToOneField मॉडल का उपयोग कर सकते हैं। इस एक-से-एक मॉडल को अक्सर एक प्रोफ़ाइल मॉडल कहा जाता है, क्योंकि यह साइट उपयोगकर्ता के बारे में गैर-सामान्य संबंधित जानकारी संग्रहीत कर सकता है। उदाहरण के लिए आप एक कर्मचारी मॉडल बना सकते हैं:

from django.contrib.auth.models import User

class Employee(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    department = models.CharField(max_length=100)

एक मौजूदा कर्मचारी फ्रेड स्मिथ को मानते हुए, जिसके पास उपयोगकर्ता और कर्मचारी मॉडल दोनों हैं, आप Django के मानक संबंधित मॉडल सम्मेलनों का उपयोग करके संबंधित जानकारी तक पहुंच सकते हैं:

>>> u = User.objects.get(username='fsmith')
>>> freds_department = u.employee.department

व्यवस्थापक पृष्ठ के उपयोगकर्ता पृष्ठ में एक प्रोफ़ाइल मॉडल के फ़ील्ड जोड़ने के लिए, एक InlineModelAdmin को परिभाषित करें (इस उदाहरण के लिए, हम आपके ऐप के StackedInline में एक StackedInline उपयोग करेंगे) और इसे एक UserAdmin वर्ग में जोड़ें, जो django.contrib.auth.models.User वर्ग के साथ पंजीकृत है:

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.models import User

from my_user_profile_app.models import Employee

# Define an inline admin descriptor for Employee model
# which acts a bit like a singleton
class EmployeeInline(admin.StackedInline):
    model = Employee
    can_delete = False
    verbose_name_plural = 'employee'

# Define a new User admin
class UserAdmin(BaseUserAdmin):
    inlines = (EmployeeInline,)

# Re-register UserAdmin
admin.site.unregister(User)
admin.site.register(User, UserAdmin)

ये प्रोफाइल मॉडल किसी भी तरह से विशेष नहीं हैं - वे सिर्फ Django मॉडल हैं जो उपयोगकर्ता मॉडल के साथ एक-से-एक लिंक होने के लिए होते हैं। इस तरह, जब उपयोगकर्ता बनाया जाता है, तो वे ऑटो नहीं बनते हैं, लेकिन django.db.models.signals.post_save का उपयोग संबंधित मॉडल को उपयुक्त बनाने या अपडेट करने के लिए किया जा सकता है।

संबंधित मॉडल का उपयोग करने से अतिरिक्त प्रश्न उत्पन्न होते हैं या संबंधित डेटा को पुनः प्राप्त करने के लिए जुड़ जाते हैं। आपकी आवश्यकताओं के आधार पर, एक कस्टम उपयोगकर्ता मॉडल जिसमें संबंधित फ़ील्ड शामिल हैं, आपके बेहतर विकल्प हो सकते हैं, हालाँकि, आपके प्रोजेक्ट के ऐप्स के भीतर डिफ़ॉल्ट उपयोगकर्ता मॉडल के मौजूदा संबंध अतिरिक्त डेटाबेस लोड को सही ठहरा सकते हैं।

कस्टम User मॉडल को प्रतिस्थापित करना

कुछ प्रकार की परियोजनाओं में प्रमाणीकरण की आवश्यकता हो सकती है जिसके लिए Django का अंतर्निहित django.contrib.auth.models.User मॉडल हमेशा उपयुक्त नहीं होता है। उदाहरण के लिए, कुछ साइटों पर यह एक उपयोगकर्ता नाम के बजाय अपनी पहचान टोकन के रूप में एक ईमेल पते का उपयोग करने के लिए अधिक समझ में आता है।

Django आपको AUTH_USER_MODEL लिए एक मान प्रदान करके डिफ़ॉल्ट उपयोगकर्ता मॉडल को ओवरराइड करने की अनुमति देता है जो एक कस्टम मॉडल का संदर्भ देता है:

AUTH_USER_MODEL = 'myapp.MyUser'

इस बिंदीदार जोड़ी में Django ऐप का नाम (जो आपके INSTALLED_APPS में होना चाहिए), और Django मॉडल का नाम है जिसे आप अपने उपयोगकर्ता मॉडल के रूप में उपयोग करना चाहते हैं।

प्रोजेक्ट शुरू करते समय कस्टम उपयोगकर्ता मॉडल का उपयोग करना

यदि आप एक नया प्रोजेक्ट शुरू कर रहे हैं, तो यह कस्टम उपयोगकर्ता मॉडल सेट करने के लिए अत्यधिक अनुशंसित है, भले ही डिफ़ॉल्ट django.contrib.auth.models.User मॉडल आपके लिए पर्याप्त हो। यह मॉडल डिफ़ॉल्ट उपयोगकर्ता मॉडल के लिए व्यावहारिक रूप से व्यवहार करता है, लेकिन आवश्यकता पड़ने पर आप इसे भविष्य में अनुकूलित कर पाएंगे:

from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
    pass

इसे AUTH_USER_MODEL इंगित करना न भूलें। किसी भी माइग्रेशन को बनाने से पहले ऐसा करें या पहली बार manage.py migrate लिए manage.py migrate

इसके अलावा, मॉडल को ऐप के admin.py में पंजीकृत करें:

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import User

admin.site.register(User, UserAdmin)

एक कस्टम उपयोगकर्ता मॉडल को मध्य-परियोजना में बदलना

डेटाबेस टेबल AUTH_USER_MODEL बाद AUTH_USER_MODEL बदलना काफी मुश्किल है क्योंकि यह विदेशी कुंजी और कई-से-कई रिश्तों को प्रभावित करता है, उदाहरण के लिए।

यह परिवर्तन स्वचालित रूप से नहीं किया जा सकता है और आपको अपने स्कीमा को मैन्युअल रूप से ठीक करने की आवश्यकता है, अपने डेटा को पुराने उपयोगकर्ता तालिका से स्थानांतरित कर रहा है, और संभवतः मैन्युअल रूप से कुछ माइग्रेशन को फिर से लागू कर रहा है। #25313 चरणों की रूपरेखा देखें।

AUTH_USER_MODEL मॉडल के लिए Django के गतिशील निर्भरता सुविधा की सीमाओं के कारण, AUTH_USER_MODEL द्वारा संदर्भित मॉडल को अपने ऐप के पहले माइग्रेशन (आमतौर पर 0001_initial ) कहा जाना 0001_initial ; अन्यथा, आपके पास निर्भरता के मुद्दे होंगे।

इसके अलावा, आप अपने माइग्रेशन को चलाने के दौरान एक CircularDependencyError डिपेंडेंसी ईयर में दौड़ सकते हैं क्योंकि Django डायनेमिक निर्भरता के कारण निर्भरता लूप को स्वचालित रूप से तोड़ने में सक्षम नहीं होगा। यदि आपको यह त्रुटि दिखाई देती है, तो आपको अपने उपयोगकर्ता मॉडल पर निर्भर मॉडलों को दूसरे माइग्रेशन में ले जाकर लूप को तोड़ देना चाहिए। (आप दो सामान्य मॉडल बनाने की कोशिश कर सकते हैं जिनमें एक-दूसरे के लिए एक makemigrations और यह देखते हुए कि कैसे makemigrations उस परिपत्र निर्भरता को हल करता है यदि आप यह देखना चाहते हैं कि यह आमतौर पर कैसे किया जाता है।)

पुन: प्रयोज्य ऐप्स और AUTH_USER_MODEL

पुन: प्रयोज्य ऐप्स को एक कस्टम उपयोगकर्ता मॉडल लागू नहीं करना चाहिए। एक परियोजना कई एप्लिकेशन और दो पुन: प्रयोज्य एप्लिकेशन का उपयोग कर सकती है जो एक कस्टम उपयोगकर्ता मॉडल को लागू करते थे एक साथ उपयोग नहीं किया जा सकता है। यदि आपको अपने एप्लिकेशन में प्रति उपयोगकर्ता जानकारी संग्रहीत करने की आवश्यकता है, तो नीचे दिए गए अनुसार OneToOneField या OneToOneField to settings.AUTH_USER_MODEL उपयोग करें।

User मॉडल का संदर्भ लेना

यदि आप django.contrib.auth.models.User सीधे संदर्भित करते हैं (उदाहरण के लिए, इसे एक विदेशी कुंजी में संदर्भित करके), तो आपका कोड उन परियोजनाओं में काम नहीं करेगा जहां AUTH_USER_MODEL सेटिंग को किसी भिन्न उपयोगकर्ता मॉडल में बदल दिया गया है।

get_user_model() [source]

सीधे django.contrib.auth.models.User को संदर्भित करने के बजाय, आपको django.contrib.auth.get_user_model() का उपयोग करके उपयोगकर्ता मॉडल का संदर्भ देना चाहिए। यह विधि वर्तमान में सक्रिय उपयोगकर्ता मॉडल को लौटा देगी - कस्टम उपयोगकर्ता मॉडल यदि कोई निर्दिष्ट है, या django.contrib.auth.models.User अन्यथा।

जब आप उपयोगकर्ता मॉडल के लिए एक विदेशी कुंजी या कई-से-कई संबंध परिभाषित करते हैं, तो आपको AUTH_USER_MODEL सेटिंग का उपयोग करके कस्टम मॉडल निर्दिष्ट करना चाहिए। उदाहरण के लिए:

from django.conf import settings
from django.db import models

class Article(models.Model):
    author = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
    )

उपयोगकर्ता मॉडल द्वारा भेजे गए संकेतों से कनेक्ट करते समय, आपको AUTH_USER_MODEL सेटिंग का उपयोग करके कस्टम मॉडल निर्दिष्ट करना चाहिए। उदाहरण के लिए:

from django.conf import settings
from django.db.models.signals import post_save

def post_save_receiver(sender, instance, created, **kwargs):
    pass

post_save.connect(post_save_receiver, sender=settings.AUTH_USER_MODEL)

सामान्यतया, यह आसान है कि कोड में AUTH_USER_MODEL सेटिंग के साथ उपयोगकर्ता मॉडल को देखें, जो आयात समय पर निष्पादित किया जाता है, हालाँकि, यह get_user_model() को कॉल करना संभव है, जबकि Django मॉडल आयात कर रहा है, इसलिए आप मॉडल का उपयोग कर सकते हैं। models.ForeignKey(get_user_model(), ...)

यदि उदाहरण के लिए @override_settings(AUTH_USER_MODEL=...) का उपयोग करके आपके ऐप को कई उपयोगकर्ता मॉडल के साथ परीक्षण किया गया है, और आप मॉड्यूल-स्तर चर में get_user_model() के परिणाम को कैश करते हैं, तो आपको get_user_model() सिग्नल को साफ़ करने के लिए सुनना पड़ सकता है। कैश। उदाहरण के लिए:

from django.apps import apps
from django.contrib.auth import get_user_model
from django.core.signals import setting_changed
from django.dispatch import receiver

@receiver(setting_changed)
def user_model_swapped(**kwargs):
    if kwargs['setting'] == 'AUTH_USER_MODEL':
        apps.clear_cache()
        from myapp import some_module
        some_module.UserModel = get_user_model()

एक कस्टम उपयोगकर्ता मॉडल निर्दिष्ट करना

मॉडल डिजाइन विचार

अपने कस्टम उपयोगकर्ता मॉडल में सीधे प्रमाणीकरण से संबंधित जानकारी को संभालने से पहले ध्यान से सोचें।

ऐप-विशिष्ट उपयोगकर्ता जानकारी को उस मॉडल में संग्रहीत करना बेहतर हो सकता है जिसका उपयोगकर्ता मॉडल के साथ संबंध है। यह प्रत्येक ऐप को अन्य ऐप के साथ संघर्ष को जोखिम में डाले बिना अपनी उपयोगकर्ता डेटा आवश्यकताओं को निर्दिष्ट करने की अनुमति देता है। दूसरी ओर, इस संबंधित जानकारी को पुनः प्राप्त करने के लिए प्रश्नों में एक डेटाबेस शामिल होगा, जिसका प्रदर्शन पर असर पड़ सकता है।

Django कुछ न्यूनतम आवश्यकताओं को पूरा करने के लिए अपने कस्टम उपयोगकर्ता मॉडल की उम्मीद करता है।

यदि आप डिफ़ॉल्ट प्रमाणीकरण बैकएंड का उपयोग करते हैं, तो आपके मॉडल में एक एकल विशिष्ट फ़ील्ड होना चाहिए जिसका उपयोग पहचान उद्देश्यों के लिए किया जा सकता है। यह एक उपयोगकर्ता नाम, एक ईमेल पता या कोई अन्य विशिष्ट विशेषता हो सकती है। यदि आप कस्टम प्रमाणीकरण बैकएंड का उपयोग करते हैं, तो एक गैर-विशिष्ट उपयोगकर्ता नाम फ़ील्ड की अनुमति दी जाती है।

कंप्लीट कस्टम यूजर मॉडल बनाने का सबसे आसान तरीका है AbstractBaseUser से वारिस करना। AbstractBaseUser हैशेड पासवर्ड और टोकन पासवर्ड रीसेट सहित उपयोगकर्ता मॉडल का मुख्य कार्यान्वयन प्रदान करता है। फिर आपको कुछ महत्वपूर्ण कार्यान्वयन विवरण प्रदान करने होंगे:

class models.CustomUser
USERNAME_FIELD

विशिष्ट पहचानकर्ता के रूप में उपयोग किए जाने वाले उपयोगकर्ता मॉडल पर फ़ील्ड के नाम का वर्णन करने वाला एक स्ट्रिंग। यह आमतौर पर किसी प्रकार का उपयोगकर्ता नाम होगा, लेकिन यह एक ईमेल पता, या कोई अन्य विशिष्ट पहचानकर्ता भी हो सकता है। फ़ील्ड अद्वितीय होना चाहिए (यानी, इसकी परिभाषा में unique=True सेट), जब तक कि आप एक कस्टम प्रमाणीकरण बैकेंड का उपयोग नहीं करते हैं जो गैर-अद्वितीय उपयोगकर्ता नाम का समर्थन कर सकते हैं।

निम्न उदाहरण में, फ़ील्ड identifier का उपयोग पहचान क्षेत्र के रूप में किया जाता है:

class MyUser(AbstractBaseUser):
    identifier = models.CharField(max_length=40, unique=True)
    ...
    USERNAME_FIELD = 'identifier'
EMAIL_FIELD

User मॉडल पर ईमेल फ़ील्ड का नाम बताने वाला एक स्ट्रिंग। यह मान get_email_field_name() द्वारा लौटाया जाता है।

REQUIRED_FIELDS

क्षेत्र के नामों की एक सूची, जो एक उपयोगकर्ता को createsuperuser प्रबंधन कमांड के माध्यम से बनाते समय संकेत दिया जाएगा। उपयोगकर्ता को इनमें से प्रत्येक क्षेत्र के लिए एक मूल्य की आपूर्ति करने के लिए प्रेरित किया जाएगा। इसमें कोई भी फ़ील्ड शामिल होना चाहिए, जिसके लिए blank False या अपरिभाषित है और इसमें उन अतिरिक्त फ़ील्ड शामिल हो सकते हैं, जिनके लिए उपयोगकर्ता द्वारा अंतःक्रियात्मक रूप से बनाए जाने के लिए संकेत मिले। REQUIRED_FIELDS का Django के अन्य हिस्सों में कोई प्रभाव नहीं है, जैसे कि व्यवस्थापक में उपयोगकर्ता बनाना।

उदाहरण के लिए, यहां एक उपयोगकर्ता मॉडल के लिए आंशिक परिभाषा है जो दो आवश्यक क्षेत्रों को परिभाषित करती है - जन्म की तारीख और ऊंचाई:

class MyUser(AbstractBaseUser):
    ...
    date_of_birth = models.DateField()
    height = models.FloatField()
    ...
    REQUIRED_FIELDS = ['date_of_birth', 'height']

ध्यान दें

REQUIRED_FIELDS आपके उपयोगकर्ता मॉडल पर सभी आवश्यक फ़ील्ड शामिल होने चाहिए, लेकिन इसमें USERNAME_FIELD या password शामिल नहीं होने चाहिए क्योंकि ये फ़ील्ड हमेशा के लिए संकेत दिए जाएंगे।

is_active

एक बूलियन विशेषता जो इंगित करती है कि उपयोगकर्ता को "सक्रिय" माना जाता है या नहीं। यह विशेषता AbstractBaseUser को True पर डिफ़ॉल्ट करने की विशेषता के रूप में प्रदान की गई है। आप इसे कैसे लागू करते हैं, यह आपके चुने हुए बैकएंड के विवरण पर निर्भर करेगा। विवरण के लिए is_active का दस्तावेज़ीकरण देखें।

get_full_name()

वैकल्पिक। उपयोगकर्ता के लिए एक लंबा औपचारिक पहचानकर्ता जैसे कि उनका पूरा नाम। यदि इसे लागू किया जाता है, तो यह किसी वस्तु के इतिहास में उपयोगकर्ता नाम के साथ django.contrib.admin में django.contrib.admin

get_short_name()

वैकल्पिक। उपयोगकर्ता के लिए एक संक्षिप्त, अनौपचारिक पहचानकर्ता जैसे कि उनका पहला नाम। यदि इसे लागू किया जाता है, तो यह यूजर को ग्रीटिंग में उपयोगकर्ता नाम django.contrib.admin के हेडर में django.contrib.admin

Django 2.0 में बदला:

पुराने संस्करणों में, उपवर्गों को get_short_name() और get_full_name() लागू करने की आवश्यकता होती है क्योंकि AbstractBaseUser में कार्यान्वयन होते हैं जो NotImplementedError

AbstractBaseUser आयात कर रहा है

AbstractBaseUser और BaseUserManager से आयात किए django.contrib.auth.base_user ताकि वे INSTALLED_APPS में django.contrib.auth को शामिल किए बिना आयात किए जा django.contrib.auth

निम्नलिखित विशेषताएँ और विधियाँ AbstractBaseUser किसी भी उपवर्ग पर उपलब्ध हैं:

class models.AbstractBaseUser
get_username()

USERNAME_FIELD द्वारा नामांकित फ़ील्ड का मान लौटाता है।

clean()

Normalize_username normalize_username() को कॉल करके उपयोगकर्ता नाम को सामान्य करता है। यदि आप इस विधि को ओवरराइड करते हैं, तो सामान्यीकरण बनाए रखने के लिए super() को कॉल करना सुनिश्चित करें।

classmethod get_email_field_name()

EMAIL_FIELD विशेषता द्वारा निर्दिष्ट ईमेल फ़ील्ड का नाम लौटाता है। यदि EMAIL_FIELD निर्दिष्ट नहीं है, तो 'email' लिए डिफ़ॉल्ट।

classmethod normalize_username(username)

NFKC यूनिकोड के उपयोगकर्ता नाम पर सामान्यीकरण लागू करता है ताकि विभिन्न यूनिकोड कोड बिंदुओं के साथ समान रूप से समान वर्णों को समान माना जाए।

is_authenticated

केवल-पढ़ने का गुण जो हमेशा True (जैसा कि AnonymousUser.is_authenticated विपरीत है जो हमेशा False )। यह यह बताने का एक तरीका है कि क्या उपयोगकर्ता को प्रमाणित किया गया है। यह किसी भी अनुमति का अर्थ नहीं है और यह जाँच नहीं करता है कि उपयोगकर्ता सक्रिय है या उसके पास एक वैध सत्र है। भले ही आम तौर पर आप request.user पर इस विशेषता की जांच करेंगे। यह पता लगाने के लिए कि क्या यह AuthenticationMiddleware (वर्तमान में लॉग-इन उपयोगकर्ता का प्रतिनिधित्व करते हुए) द्वारा आबाद किया गया है, आपको पता होना चाहिए कि यह विशेषता किसी भी django.contrib.auth.models.User उदाहरण के लिए True

is_anonymous

पढ़ें-केवल विशेषता जो हमेशा False । यह django.contrib.auth.models.User और django.contrib.auth.models.AnonymousUser वस्तुओं को अलग करने का एक तरीका है। आम तौर पर, आपको इस विशेषता के लिए is_authenticated का उपयोग करना पसंद करना चाहिए।

set_password(raw_password)

पासवर्ड हैशिंग का ध्यान रखते हुए, दिए गए कच्चे स्ट्रिंग में उपयोगकर्ता का पासवर्ड सेट करता है। AbstractBaseUser ऑब्जेक्ट को सहेजता नहीं है।

जब raw_password None , तो पासवर्ड अनुपयोगी पासवर्ड पर सेट हो जाएगा, जैसे कि set_unusable_password() का उपयोग किया गया था।

check_password(raw_password)

यदि दिया गया कच्चा स्ट्रिंग उपयोगकर्ता के लिए सही पासवर्ड है तो सही है। (यह तुलना करने में पासवर्ड हैशिंग का ध्यान रखता है।)

set_unusable_password()

पासवर्ड सेट न होने के कारण उपयोगकर्ता को चिह्नित करता है। यह पासवर्ड के लिए रिक्त स्ट्रिंग के समान नहीं है। इस उपयोगकर्ता के लिए check_password() कभी भी वापस नहीं आएगा। AbstractBaseUser ऑब्जेक्ट को सहेजता नहीं है।

यदि आपके आवेदन के लिए प्रमाणीकरण किसी मौजूदा बाहरी स्रोत जैसे LDAP निर्देशिका के लिए होता है, तो आपको इसकी आवश्यकता हो सकती है।

has_usable_password()

यदि इस उपयोगकर्ता के लिए set_unusable_password() कहा जाता है, तो False रिटर्न देता है।

get_session_auth_hash()

पासवर्ड फ़ील्ड का एक HMAC लौटाता है। पासवर्ड परिवर्तन पर सत्र अमान्य के लिए उपयोग किया जाता है।

AbstractUser उपवर्ग: AbstractBaseUser :

class models.AbstractUser
clean()

BaseUserManager.normalize_email() कॉल करके ईमेल को सामान्य करता है। यदि आप इस विधि को ओवरराइड करते हैं, तो सामान्यीकरण बनाए रखने के लिए super() को कॉल करना सुनिश्चित करें।

कस्टम उपयोगकर्ता मॉडल के लिए प्रबंधक लिखना

आपको अपने उपयोगकर्ता मॉडल के लिए एक कस्टम प्रबंधक भी परिभाषित करना चाहिए। यदि आपका उपयोगकर्ता मॉडल username , email , is_staff , is_staff , is_active , is_superuser , और date_joined फ़ील्ड को Django के डिफ़ॉल्ट उपयोगकर्ता के समान परिभाषित करता है, तो आप सिर्फ Django के उपयोगकर्ता date_joined स्थापित कर सकते हैं; हालाँकि, यदि आपका उपयोगकर्ता मॉडल विभिन्न क्षेत्रों को परिभाषित करता है, तो आपको एक कस्टम प्रबंधक को परिभाषित करने की आवश्यकता होगी, जो दो अतिरिक्त तरीके प्रदान करते हुए BaseUserManager को विस्तारित करता है:

class models.CustomUserManager
create_user(*username_field*, password=None, **other_fields)

create_user() प्रोटोटाइप को उपयोगकर्ता नाम फ़ील्ड को स्वीकार करना चाहिए, साथ ही सभी आवश्यक फ़ील्ड को तर्क के रूप में स्वीकार करना चाहिए। उदाहरण के लिए, यदि आपका उपयोगकर्ता मॉडल उपयोगकर्ता नाम के रूप में email का उपयोग करता है, और उसके पास आवश्यक फ़ील्ड के रूप में date_of_birth , तो create_user को इस रूप में परिभाषित किया जाना चाहिए:

def create_user(self, email, date_of_birth, password=None):
    # create user here
    ...
create_superuser(*username_field*, password, **other_fields)

create_superuser() प्रोटोटाइप को उपयोगकर्ता नाम फ़ील्ड को स्वीकार करना चाहिए, साथ ही सभी आवश्यक फ़ील्ड को तर्क के रूप में स्वीकार करना चाहिए। उदाहरण के लिए, यदि आपका उपयोगकर्ता मॉडल उपयोगकर्ता नाम के रूप में email का उपयोग करता है, और उसके पास आवश्यक फ़ील्ड के रूप में date_of_birth , तो create_superuser को इस रूप में परिभाषित किया जाना चाहिए:

def create_superuser(self, email, date_of_birth, password):
    # create superuser here
    ...

create_user() विपरीत, create_superuser() को पासवर्ड प्रदान करने के लिए कॉलर की आवश्यकता होगी।

USERNAME_FIELD या REQUIRED_FIELDS में किसी to_field के लिए, ये विधियाँ मौजूदा उदाहरण के to_field ( primary_key रूप से डिफ़ॉल्ट रूप से प्राथमिक) का मान प्राप्त करती हैं।

BaseUserManager निम्नलिखित उपयोगिता विधियाँ प्रदान करता है:

class models.BaseUserManager
classmethod normalize_email(email)

ईमेल पते के डोमेन भाग को कम करके ईमेल पते को सामान्य करता है।

get_by_natural_key(username)

USERNAME_FIELD द्वारा नामांकित फ़ील्ड की सामग्री का उपयोग करके उपयोगकर्ता का उदाहरण प्राप्त करता है।

make_random_password(length=10, allowed_chars='abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789')

अनुमत वर्णों की दी गई लंबाई और दिए गए स्ट्रिंग के साथ एक यादृच्छिक पासवर्ड लौटाता है। ध्यान दें कि allowed_chars के डिफ़ॉल्ट मान में ऐसे अक्षर शामिल नहीं हैं जो उपयोगकर्ता भ्रम पैदा कर सकते हैं, जिनमें शामिल हैं:

  • i , l , I और 1 (लोअरकेस अक्षर i, लोअरकेस अक्षर L, अपरकेस अक्षर i, और नंबर एक)
  • o , O और 0 (निचला अक्षर o, अपरकेस अक्षर o और शून्य)

Django के डिफ़ॉल्ट User का विस्तार

यदि आप Django के django.contrib.auth.models.User मॉडल से पूरी तरह से खुश हैं और आप केवल कुछ अतिरिक्त प्रोफ़ाइल जानकारी जोड़ना चाहते हैं, तो आप बस AbstractUser subclass कर सकते हैं और अपने कस्टम प्रोफ़ाइल फ़ील्ड जोड़ सकते हैं, हालाँकि हम एक अलग मॉडल की अनुशंसा करेंगे एक कस्टम उपयोगकर्ता मॉडल निर्दिष्ट करने के "मॉडल डिजाइन विचार" नोट में वर्णित है। AbstractUser एक अमूर्त मॉडल के रूप में डिफ़ॉल्ट django.contrib.auth.models.User का पूर्ण कार्यान्वयन प्रदान करता है।

कस्टम उपयोगकर्ता और अंतर्निर्मित रूप

Django के अंतर्निहित forms और views उपयोगकर्ता मॉडल के बारे में कुछ धारणाएं बनाते हैं जिनके साथ वे काम कर रहे हैं।

निम्नलिखित रूप AbstractBaseUser किसी भी उपवर्ग के साथ संगत हैं:

निम्नलिखित रूप उपयोगकर्ता मॉडल के बारे में धारणा बनाते हैं और इसका उपयोग इस तरह किया जा सकता है जैसे कि उन मान्यताओं को पूरा किया जाता है:

  • PasswordResetForm : मान लें कि उपयोगकर्ता मॉडल में एक फ़ील्ड है जो get_email_field_name() (डिफ़ॉल्ट रूप से email get_email_field_name() द्वारा लौटाए गए उपयोगकर्ता के ईमेल पते को संग्रहीत करता है, जिसका उपयोग उपयोगकर्ता की पहचान करने के लिए किया जा सकता है और निष्क्रिय उपयोगकर्ताओं के लिए पासवर्ड रीसेट को रोकने के लिए। ।

अंत में, निम्न प्रपत्र django.contrib.auth.models.User से जुड़े होते हैं और कस्टम उपयोगकर्ता मॉडल के साथ काम करने के लिए उन्हें फिर से लिखना या विस्तारित करना पड़ता है:

यदि आपका कस्टम उपयोगकर्ता मॉडल AbstractUser का एक सरल उपवर्ग है, तो आप इन रूपों को इस तरीके से बढ़ा सकते हैं:

from django.contrib.auth.forms import UserCreationForm
from myapp.models import CustomUser

class CustomUserCreationForm(UserCreationForm):

    class Meta(UserCreationForm.Meta):
        model = CustomUser
        fields = UserCreationForm.Meta.fields + ('custom_field',)

कस्टम उपयोगकर्ता और django.contrib.admin

यदि आप चाहते हैं कि आपका कस्टम उपयोगकर्ता मॉडल भी व्यवस्थापक के साथ काम करे, तो आपके उपयोगकर्ता मॉडल को कुछ अतिरिक्त विशेषताओं और विधियों को परिभाषित करना होगा। ये विधियाँ व्यवस्थापक को विषयवस्तु के लिए उपयोगकर्ता की पहुँच को नियंत्रित करने की अनुमति देती हैं:

class models.CustomUser
is_staff

यदि उपयोगकर्ता को व्यवस्थापक साइट तक पहुंच की अनुमति है तो यह True

is_active

यदि उपयोगकर्ता खाता वर्तमान में सक्रिय है, तो यह True है।

has_perm(perm, obj=None):

यदि उपयोगकर्ता के पास नाम की अनुमति है तो यह True । यदि obj प्रदान किया जाता है, तो अनुमति को एक विशिष्ट ऑब्जेक्ट उदाहरण के खिलाफ obj की आवश्यकता होती है।

has_module_perms(app_label):

यदि उपयोगकर्ता दिए गए ऐप में मॉडल एक्सेस करने की अनुमति देता है तो यह True

आपको व्यवस्थापक के साथ अपने कस्टम उपयोगकर्ता मॉडल को पंजीकृत करने की भी आवश्यकता होगी। यदि आपका कस्टम उपयोगकर्ता मॉडल django.contrib.auth.models.AbstractUser तक django.contrib.auth.models.AbstractUser , तो आप Django के मौजूदा django.contrib.auth.admin.UserAdmin वर्ग का उपयोग कर सकते हैं। हालाँकि, यदि आपका उपयोगकर्ता मॉडल AbstractBaseUser विस्तार करता है, तो आपको एक कस्टम ModelAdmin वर्ग को परिभाषित करने की आवश्यकता होगी। डिफ़ॉल्ट django.contrib.auth.admin.UserAdmin को उप- django.contrib.auth.admin.UserAdmin करना संभव हो सकता है; हालाँकि, आपको किसी भी परिभाषा को ओवरराइड करने की आवश्यकता होगी जो कि django.contrib.auth.models.AbstractUser पर फ़ील्ड को django.contrib.auth.models.AbstractUser जो आपके कस्टम उपयोगकर्ता वर्ग पर नहीं हैं।

कस्टम उपयोगकर्ता और अनुमतियाँ

Django की अनुमति के ढांचे को अपने उपयोगकर्ता वर्ग में शामिल करना आसान बनाने के लिए, Django PermissionsMixin प्रदान करता है। यह एक अमूर्त मॉडल है जिसे आप अपने उपयोगकर्ता मॉडल के लिए श्रेणी पदानुक्रम में शामिल कर सकते हैं, जो आपको Django के अनुमति मॉडल का समर्थन करने के लिए आवश्यक सभी तरीके और डेटाबेस फ़ील्ड प्रदान करते हैं।

PermissionsMixin निम्नलिखित तरीके और विशेषताएँ प्रदान करती है:

class models.PermissionsMixin
is_superuser

बूलियन। यह निर्दिष्ट करता है कि इस उपयोगकर्ता के पास स्पष्ट रूप से निर्दिष्ट किए बिना सभी अनुमतियां हैं।

get_group_permissions(obj=None)

उपयोगकर्ता द्वारा अपने समूहों के माध्यम से अनुमति स्ट्रिंग का एक सेट लौटाता है।

यदि obj पास हो जाता है, तो केवल इस विशिष्ट ऑब्जेक्ट के लिए समूह की अनुमति देता है।

get_all_permissions(obj=None)

अनुमति स्ट्रिंग का एक सेट लौटाता है जो उपयोगकर्ता के पास समूह और उपयोगकर्ता अनुमतियों के माध्यम से होता है।

यदि obj पास हो जाता है, तो केवल इस विशिष्ट ऑब्जेक्ट के लिए अनुमति देता है।

has_perm(perm, obj=None)

यदि उपयोगकर्ता के पास निर्दिष्ट अनुमति है तो यह True , जहाँ अनुमति प्रारूप में है "<app label>.<permission codename>" ( permissions देखें)। यदि उपयोगकर्ता निष्क्रिय है, तो यह विधि हमेशा False लौटेगी।

यदि obj पास हो जाता है, तो यह विधि मॉडल की अनुमति के लिए नहीं, बल्कि इस विशिष्ट ऑब्जेक्ट के लिए जाँच करेगी।

has_perms(perm_list, obj=None)

यदि उपयोगकर्ता के पास प्रत्येक निर्दिष्ट अनुमतियाँ हैं, तो यह True , जहाँ प्रत्येक अनुमति "<app label>.<permission codename>" प्रारूप में है। यदि उपयोगकर्ता निष्क्रिय है, तो यह विधि हमेशा False लौटेगी।

यदि obj पास हो जाता है, तो यह विधि मॉडल के लिए अनुमतियों के लिए नहीं, बल्कि विशिष्ट ऑब्जेक्ट के लिए जाँच करेगी।

has_module_perms(package_name)

यदि उपयोगकर्ता दिए गए पैकेज (Django ऐप लेबल) में कोई अनुमति है तो True । यदि उपयोगकर्ता निष्क्रिय है, तो यह विधि हमेशा False लौटेगी।

PermissionsMixin और ModelBackend

यदि आप PermissionsMixin शामिल नहीं करते हैं, तो आपको यह सुनिश्चित करना चाहिए कि आप ModelBackend पर अनुमतियों के तरीकों को लागू न करें। ModelBackend मानता है कि आपके उपयोगकर्ता मॉडल पर कुछ फ़ील्ड उपलब्ध हैं। यदि आपका उपयोगकर्ता मॉडल उन क्षेत्रों को प्रदान नहीं करता है, तो आप अनुमतियों की जांच करते समय डेटाबेस त्रुटियां प्राप्त करेंगे।

कस्टम उपयोगकर्ता और प्रॉक्सी मॉडल

कस्टम उपयोगकर्ता मॉडल की एक सीमा यह है कि एक कस्टम उपयोगकर्ता मॉडल स्थापित करने से उपयोगकर्ता के किसी भी प्रॉक्सी मॉडल को तोड़ दिया जाएगा। प्रॉक्सी मॉडल एक ठोस आधार वर्ग पर आधारित होना चाहिए; एक कस्टम उपयोगकर्ता मॉडल को परिभाषित करके, आप बेस क्लास को मज़बूती से पहचानने के लिए Django की क्षमता को हटा देते हैं।

यदि आपका प्रोजेक्ट प्रॉक्सी मॉडल का उपयोग करता है, तो आपको अपने प्रोजेक्ट में उपयोग होने वाले उपयोगकर्ता मॉडल को विस्तारित करने के लिए प्रॉक्सी को संशोधित करना होगा, या अपने django.contrib.auth.models.User उपवर्ग में अपने प्रॉक्सी के व्यवहार को मर्ज करना होगा।

एक पूर्ण उदाहरण

यहां एक व्यवस्थापक-अनुरूप कस्टम उपयोगकर्ता ऐप का एक उदाहरण है। यह उपयोगकर्ता मॉडल उपयोगकर्ता नाम के रूप में एक ईमेल पते का उपयोग करता है, और इसमें आवश्यक जन्म तिथि होती है; यह उपयोगकर्ता खाते पर एक साधारण admin ध्वज से परे कोई अनुमति जाँच प्रदान करता है। यह मॉडल उपयोगकर्ता के निर्माण रूपों को छोड़कर सभी अंतर्निहित रूपों और विचारों के अनुकूल होगा। यह उदाहरण दिखाता है कि अधिकांश घटक एक साथ कैसे काम करते हैं, लेकिन उत्पादन के उपयोग के लिए सीधे परियोजनाओं में कॉपी किए जाने का इरादा नहीं है।

यह कोड सभी एक कस्टम प्रमाणीकरण ऐप के लिए एक models.py फ़ाइल में रहेगा:

from django.db import models
from django.contrib.auth.models import (
    BaseUserManager, AbstractBaseUser
)


class MyUserManager(BaseUserManager):
    def create_user(self, email, date_of_birth, password=None):
        """
        Creates and saves a User with the given email, date of
        birth and password.
        """
        if not email:
            raise ValueError('Users must have an email address')

        user = self.model(
            email=self.normalize_email(email),
            date_of_birth=date_of_birth,
        )

        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, date_of_birth, password):
        """
        Creates and saves a superuser with the given email, date of
        birth and password.
        """
        user = self.create_user(
            email,
            password=password,
            date_of_birth=date_of_birth,
        )
        user.is_admin = True
        user.save(using=self._db)
        return user


class MyUser(AbstractBaseUser):
    email = models.EmailField(
        verbose_name='email address',
        max_length=255,
        unique=True,
    )
    date_of_birth = models.DateField()
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)

    objects = MyUserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['date_of_birth']

    def __str__(self):
        return self.email

    def has_perm(self, perm, obj=None):
        "Does the user have a specific permission?"
        # Simplest possible answer: Yes, always
        return True

    def has_module_perms(self, app_label):
        "Does the user have permissions to view the app `app_label`?"
        # Simplest possible answer: Yes, always
        return True

    @property
    def is_staff(self):
        "Is the user a member of staff?"
        # Simplest possible answer: All admins are staff
        return self.is_admin

फिर, Django के व्यवस्थापक के साथ इस कस्टम उपयोगकर्ता मॉडल को पंजीकृत करने के लिए, एप्लिकेशन की admin.py फ़ाइल में निम्न कोड की आवश्यकता होगी :

from django import forms
from django.contrib import admin
from django.contrib.auth.models import Group
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.forms import ReadOnlyPasswordHashField

from customauth.models import MyUser


class UserCreationForm(forms.ModelForm):
    """A form for creating new users. Includes all the required
    fields, plus a repeated password."""
    password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
    password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)

    class Meta:
        model = MyUser
        fields = ('email', 'date_of_birth')

    def clean_password2(self):
        # Check that the two password entries match
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")
        if password1 and password2 and password1 != password2:
            raise forms.ValidationError("Passwords don't match")
        return password2

    def save(self, commit=True):
        # Save the provided password in hashed format
        user = super().save(commit=False)
        user.set_password(self.cleaned_data["password1"])
        if commit:
            user.save()
        return user


class UserChangeForm(forms.ModelForm):
    """A form for updating users. Includes all the fields on
    the user, but replaces the password field with admin's
    password hash display field.
    """
    password = ReadOnlyPasswordHashField()

    class Meta:
        model = MyUser
        fields = ('email', 'password', 'date_of_birth', 'is_active', 'is_admin')

    def clean_password(self):
        # Regardless of what the user provides, return the initial value.
        # This is done here, rather than on the field, because the
        # field does not have access to the initial value
        return self.initial["password"]


class UserAdmin(BaseUserAdmin):
    # The forms to add and change user instances
    form = UserChangeForm
    add_form = UserCreationForm

    # The fields to be used in displaying the User model.
    # These override the definitions on the base UserAdmin
    # that reference specific fields on auth.User.
    list_display = ('email', 'date_of_birth', 'is_admin')
    list_filter = ('is_admin',)
    fieldsets = (
        (None, {'fields': ('email', 'password')}),
        ('Personal info', {'fields': ('date_of_birth',)}),
        ('Permissions', {'fields': ('is_admin',)}),
    )
    # add_fieldsets is not a standard ModelAdmin attribute. UserAdmin
    # overrides get_fieldsets to use this attribute when creating a user.
    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': ('email', 'date_of_birth', 'password1', 'password2')}
        ),
    )
    search_fields = ('email',)
    ordering = ('email',)
    filter_horizontal = ()

# Now register the new UserAdmin...
admin.site.register(MyUser, UserAdmin)
# ... and, since we're not using Django's built-in permissions,
# unregister the Group model from admin.
admin.site.unregister(Group)

अंत में, कस्टम मॉडल को अपने प्रोजेक्ट में AUTH_USER_MODEL सेटिंग का उपयोग करके अपने प्रोजेक्ट के लिए डिफ़ॉल्ट उपयोगकर्ता मॉडल के रूप में निर्दिष्ट करें settings.py :

AUTH_USER_MODEL = 'customauth.MyUser'

Original text