Django के self.client.login (…) इकाई परीक्षणों में काम नहीं करता है


83

मैंने अपनी इकाई परीक्षणों के लिए उपयोगकर्ताओं को दो तरीकों से बनाया है:

1) "dif.user" के लिए एक स्थिरता बनाएं जो लगभग इस तरह दिखता है:

    { 
        "pk": 1, 
        "model": "auth.user", 
        "fields": { 
            "username": "homer", 
            "is_active": 1, 
            "password": 
"sha1$72cd3$4935449e2cd7efb8b3723fb9958fe3bb100a30f2", 
            ... 
        } 
    }

मैं प्रतीत होता है महत्वहीन भागों को छोड़ दिया है।

2) सेटअप फ़ंक्शन में 'create_user' का उपयोग करें (हालांकि मैं अपने फिक्स्चर वर्ग में सब कुछ रखना चाहूंगा):

def setUp(self): 
       User.objects.create_user('homer', 'ho...@simpson.net', 'simpson') 

ध्यान दें कि पासवर्ड दोनों मामलों में सिम्पसन है।

मैंने सत्यापित किया है कि यह जानकारी सही तरीके से परीक्षण डेटाबेस समय और समय में लोड की जा रही है। मैं User.objects.get का उपयोग करके उपयोगकर्ता ऑब्जेक्ट को पकड़ सकता हूं। मैं सत्यापित कर सकता हूं कि पासवर्ड 'check_password' का उपयोग करके सही है। उपयोगकर्ता सक्रिय है।

फिर भी, हमेशा के लिए, self.client.login (उपयोगकर्ता नाम = 'होमर', पासवर्ड = 'सिम्पसन') नाखून। मैं क्यों के रूप में चकित हूँ। मुझे लगता है कि मैंने इससे संबंधित हर एक इंटरनेट चर्चा को पढ़ा है। क्या कोई मदद कर सकता है?

मेरी इकाई परीक्षा में लॉगिन कोड इस तरह दिखता है:

    login = self.client.login(username='homer', password='simpson') 
    self.assertTrue(login) 

धन्यवाद।


1
आपको क्या त्रुटि संदेश मिला है?
zs2020

परीक्षण मामला लाइन पर विफल रहता है, 'self.assertTrue (login)'; लॉगिन () फ़ंक्शन गलत देता है।
Thebossman

1
मैंने मूल रूप से आपकी दूसरी भिन्नता को कॉपी और पेस्ट किया है और यह Django 1.3 पर काम करता है। क्या आप आयात सहित पूरे कोड को पोस्ट कर सकते हैं?
Liorsion

इसे एक कोड बेस में कहीं दफन किया गया है जिसका अब मैं उपयोग नहीं कर सकता। अगर मुझे समस्या आती है तो मैं फॉलो-अप ज़रूर करूँगा, लेकिन रिकॉर्ड के लिए, यह Django के पुराने संस्करण के साथ था; मुझे लगता है कि 1.0.2।
Thebossman

जवाबों:


122

कोड जो काम नहीं करता है:

from django.contrib.auth.models import User
from django.test import Client

user = User.objects.create(username='testuser', password='12345')

c = Client()
logged_in = c.login(username='testuser', password='12345')

यह काम क्यों नहीं करता है?

ऊपर दिए गए स्निपेट में, जब Userवास्तविक पासवर्ड हैश बनाया जाता है 12345। जब क्लाइंट loginविधि को कॉल करता है, तो passwordतर्क का मान 12345, हैश फ़ंक्शन से गुजरता है, जिसके परिणामस्वरूप कुछ ऐसा होता है

hash('12345') = 'adkfh5lkad438....'

यह तब डेटाबेस में संग्रहीत हैश की तुलना में होता है, और क्लाइंट को एक्सेस से वंचित कर दिया जाता है 'adkfh5lkad438....' != '12345'

समाधान

उचित कार्य करने के लिए set_passwordफ़ंक्शन को कॉल करना है , जो दिए गए स्ट्रिंग को हैश फ़ंक्शन से गुजरता है और परिणाम को संग्रहीत करता है User.password

इसके अलावा, कॉल करने के बाद set_passwordहमें Userडेटाबेस में अपडेट की गई वस्तु को सहेजना होगा :

user = User.objects.create(username='testuser')
user.set_password('12345')
user.save()

c = Client()
logged_in = c.login(username='testuser', password='12345')

44
आप एक उपयोग करते हैं User.objects.create_superuser()और User.objects.create_user()यह बिल्कुल इस set_password()कॉल को निष्पादित करता है ।
vdboor

कैसे के बारे में जब आप एक व्यक्ति को लॉग इन करते हैं
चट्टानी एक प्रकार का जानवर

@vdboor टिप्पणी में जोड़ने के लिए: ध्यान दें कि चूंकि Django 1.4 भी User.objects.get_or_create()आवश्यक set_password()कॉल करता है
फरिन्स

53

एक आसान तरीका है force_login, जो Django 1.9 में उपयोग करना है ।

force_login(user, backend=None)

उदाहरण के लिए:

class LoginView(TestCase):
    def setUp(self):
        self.client.force_login(User.objects.get_or_create(username='testuser')[0])

5

क्या आप नीचे की तरह देख सकते हैं,

from django.test import TransactionTestCase, Client

class UserHistoryTest(TransactionTestCase):
    self.user = User.objects.create(username='admin', password='pass@123', email='admin@admin.com')
    self.client = Client() # May be you have missed this line

    def test_history(self):
        self.client.login(username=self.user.username, password='pass@123')
        # get_history function having login_required decorator
        response = self.client.post(reverse('get_history'), {'user_id': self.user.id})
        self.assertEqual(response.status_code, 200)

इस टेस्ट केस ने मेरे लिए काम किया।


5

जो चेक django.contrib.sessionsमें जोड़ा गया है INSTALLED_APPSक्योंकि client.login()चेक है कि यह है और हमेशा गलत होगा यदि यह नहीं है:

https://docs.djangoproject.com/es/1.9/topics/http/sessions/#enabling-sessions


2
इसके लिए +1। यहां तक कि साथ django.contrib.sessions.middleware.SessionMiddlewareमिडलवेयर classses में आप अभी भी django.test.Client के माध्यम से प्रवेश नहीं कर सकते। मुझे इस उत्तर को खोजने में एक सप्ताह का समय लगता है
शिष्य

0
from django.test import TestCase
from django.contrib.auth.models import User
from django.test import Client
class MyProfile(TestCase):
    @classmethod
    def setUpClass(self):
        self.username = 'dummy' + data + '@gmail.com'
        self.password = 'Dummy@123'
        user = User.objects.create(username=self.username)
        user.set_password(self.password)
        user.save()
        c = Client()
        self.client_object = c.login(username=self.username, password=self.password)
        self.content_type = "application/json"
        response = self.client_object.post('/api/my-profile/', content_type=self.content_type)

-3

अगर कोई अभी भी इसका अनुसरण कर रहा है, तो मुझे लगता है कि 'is_staff' और 'is_active' की विशेषताओं को सफलतापूर्वक लॉग इन करने के लिए ट्रू रखा जाना चाहिए ...

self.user = User.objects.create(username='testuser',password='pwd',is_active=1,is_staff=1)


4
यह सिर्फ ........... self.user = User.objects.create (उपयोगकर्ता नाम = 'testuser', पासवर्ड = '12345', is_active = True, is_staff = True, is_superuser = True =) पर काम करता है। user.set_password ('हैलो') self.user.save () उपयोगकर्ता = प्रमाणित (उपयोगकर्ता नाम = 'testuser', पासवर्ड = 'hello') लॉगिन = self.c.login (उपयोगकर्ता नाम = 'testuser', पासवर्ड = 'hello' ) सेल्फ.ट्रेट ट्रू (लॉगिन)
अरिंदम रॉयचौधरी

इसका ऐसा कुछ भी नहीं है is_staffजो सामान्य रूप से व्यवस्थापक पैनल के लिए घर का उपयोग करने की अनुमति देता है। जैसा कि आप देख सकते हैं कि शुरुआती पोस्टिंग में डेटा पहले से ही है is_active = 1और यही इसके लिए डिफ़ॉल्ट भी है User.objects.create()
9

1
@arindamroychowdhury - वाह, कि वास्तव में काम किया .. (आपकी टिप्पणी, वह है)
रिचर्ड डे विट

1
यह एक संस्करण समस्या हो सकती है, लेकिन मुझे आपकी प्रामाणिक कॉल पर टिप्पणी करनी होगी। इसके अलावा, आपकी टिप्पणी एक विजेता की तरह काम करती है! आगे के परीक्षण के विचार पर, मैंने पाया कि is_active, is_superuser, और is_staff सभी अनावश्यक थे। बात यह है कि यह set_password को कॉल था।
dolphus333
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.