Django 2.1 - Customizing authentication in 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
ऑब्जेक्ट हो सकता है, बैकएंड को अनाम उपयोगकर्ताओं के लिए कस्टम प्राधिकरण व्यवहार निर्दिष्ट करने की अनुमति देता है।
यह पुन: उपयोग करने योग्य ऐप्स के लेखकों के लिए विशेष रूप से उपयोगी है, जो अनाम पहुँच को नियंत्रित करने के लिए, सेटिंग्स की आवश्यकता के बजाय, सामान्य बैकएंड पर प्राधिकरण के सभी प्रश्नों को निर्दिष्ट कर सकते हैं।
निष्क्रिय उपयोगकर्ताओं के लिए प्राधिकरण
यदि आप निष्क्रिय उपयोगकर्ताओं को प्रमाणित करने की अनुमति देना चाहते हैं, तो आप
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
किसी भी उपवर्ग के साथ संगत हैं:
-
AuthenticationForm
:USERNAME_FIELD
द्वारा निर्दिष्ट उपयोगकर्ता नाम फ़ील्ड का उपयोग करता है। -
SetPasswordForm
-
PasswordChangeForm
-
AdminPasswordChangeForm
निम्नलिखित रूप उपयोगकर्ता मॉडल के बारे में धारणा बनाते हैं और इसका उपयोग इस तरह किया जा सकता है जैसे कि उन मान्यताओं को पूरा किया जाता है:
-
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
लौटेगी।
-
कस्टम उपयोगकर्ता और प्रॉक्सी मॉडल
कस्टम उपयोगकर्ता मॉडल की एक सीमा यह है कि एक कस्टम उपयोगकर्ता मॉडल स्थापित करने से उपयोगकर्ता के किसी भी प्रॉक्सी मॉडल को तोड़ दिया जाएगा। प्रॉक्सी मॉडल एक ठोस आधार वर्ग पर आधारित होना चाहिए; एक कस्टम उपयोगकर्ता मॉडल को परिभाषित करके, आप बेस क्लास को मज़बूती से पहचानने के लिए 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'
