Hi Ashish, I know it's been long since you worked on this problem. I am not able to get past this error despite trying these solution. Is there a permanent sort of fix for this problem? could you please help me out. Thanks!
On Wednesday, June 24, 2015 at 3:43:45 AM UTC+5:30, Ashish Khatkar wrote: > > Hi, > Today I was trying to do user authentication with Django + MongoDB. I was > constantly getting "Metadict object has no attribute pk" error. I searched > for the fix but nothing helped. In the end, I read the implementation of > login function and changed request.session[SESSION_KEY] = > user._meta.pk.value_to_string(user) to request.session[SESSION_KEY] = > user.id in django/contrib/auth/__init__.py and correspondingly changed > return int(value) line no 947 to return value in > django/db/models/fields/__init__.py as automated primary key for mongo db > is a hexadecimal string. It worked this way. > Is there any other way to achieve same thing ? If not should I create a PR > to fix this. > > My settings.py > """ > Django settings for testApp project. > > Generated by 'django-admin startproject' using Django 1.8.2. > > For more information on this file, see > https://docs.djangoproject.com/en/1.8/topics/settings/ > > For the full list of settings and their values, see > https://docs.djangoproject.com/en/1.8/ref/settings/ > """ > > # Build paths inside the project like this: os.path.join(BASE_DIR, ...) > import os > > BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) > > > # Quick-start development settings - unsuitable for production > # See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/ > > # SECURITY WARNING: keep the secret key used in production secret! > SECRET_KEY = ')s&uno-o3x)v^1-2bjt4o8*(sf^8zw42+#tvm(&km&fs+39x!5' > > # SECURITY WARNING: don't run with debug turned on in production! > DEBUG = True > > ALLOWED_HOSTS = ["localhost"] > > > # Application definition > > INSTALLED_APPS = ( > 'django.contrib.admin', > 'django.contrib.auth', > 'django.contrib.contenttypes', > 'django.contrib.sessions', > 'django.contrib.messages', > 'django.contrib.staticfiles', > 'meriApp', > ) > > MIDDLEWARE_CLASSES = ( > 'django.contrib.sessions.middleware.SessionMiddleware', > 'django.middleware.common.CommonMiddleware', > 'django.middleware.csrf.CsrfViewMiddleware', > 'django.contrib.auth.middleware.AuthenticationMiddleware', > 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', > 'django.contrib.messages.middleware.MessageMiddleware', > 'django.middleware.clickjacking.XFrameOptionsMiddleware', > 'django.middleware.security.SecurityMiddleware', > ) > > ROOT_URLCONF = 'testApp.urls' > > TEMPLATES = [ > { > 'BACKEND': 'django.template.backends.django.DjangoTemplates', > 'DIRS': [], > 'APP_DIRS': True, > 'OPTIONS': { > 'context_processors': [ > 'django.template.context_processors.debug', > 'django.template.context_processors.request', > 'django.contrib.auth.context_processors.auth', > 'django.contrib.messages.context_processors.messages', > ], > }, > }, > ] > > WSGI_APPLICATION = 'testApp.wsgi.application' > > > # Database > # https://docs.djangoproject.com/en/1.8/ref/settings/#databases > > # DATABASES = { > # 'default': { > # 'ENGINE': 'django.db.backends.sqlite3', > # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), > # } > # } > > > # Internationalization > # https://docs.djangoproject.com/en/1.8/topics/i18n/ > > LANGUAGE_CODE = 'en-us' > > TIME_ZONE = 'Asia/Kolkata' > > USE_I18N = True > > USE_L10N = True > > USE_TZ = True > > > # Static files (CSS, JavaScript, Images) > # https://docs.djangoproject.com/en/1.8/howto/static-files/ > > STATIC_URL = '/static/' > > LOGIN_URL = '' > > LOGIN_REDIRECT_URL = '/meriApp/' > > import mongoengine > > DATABASES = { > 'default': { > 'ENGINE': 'django.db.backends.dummy', > }, > } > > SESSION_ENGINE = 'mongoengine.django.sessions' # optional > # _MONGODB_USER = '' > # _MONGODB_PASSWD = '' > # _MONGODB_HOST = '' > > _MONGODB_NAME = 'test' > > # _MONGODB_DATABASE_HOST = \ > # 'mongodb://%s:%s@%s/%s' \ > # % (_MONGODB_USER, _MONGODB_PASSWD, _MONGODB_HOST, _MONGODB_NAME) > > # mongoengine.connect(_MONGODB_NAME, host=_MONGODB_DATABASE_HOST) > mongoengine.connect(_MONGODB_NAME) > AUTHENTICATION_BACKENDS = ( > 'mongoengine.django.auth.MongoEngineBackend', > ) > > This is the view with which I am authenticating : > Enter code here...@csrf_protect > def login_view(request): > if request.method == 'GET': > return render_to_response('index.html', context_instance= > RequestContext(request)) > elif request.method == 'POST': > try: > username = request.POST['email'] > password = request.POST['password'] > user = User.objects.get(username=username) > if user.check_password(password): > user.backend = 'mongoengine.django.auth. > MongoEngineBackend' > user = authenticate(username=username, > password=password) > > login(request, user) > return HttpResponseRedirect('/ > meriApp/dashboard') > else: > return render_to_response('index.html', {'msg' : > "Invalid Email/Password"}, context_instance=RequestContext(request)) > except DoesNotExist: > return render_to_response('index.html', {'msg' : "This > user doesn't exist"}, context_instance=RequestContext(request)) > > > Changes I did in django/contrib/auth/__init__.py : > try: > request.session[SESSION_KEY] = user._meta.pk.value_to_string(user) > except Exception: > request.session[SESSION_KEY] = user.id > > > Changes I did in django/contrib/auth/__init__.py : > try: return int(value) except ValueError: try: # As mongoDB id is hex > string, try to parse it. # If it raises exception than raise validation > error # else return the hex string int(value, 16) return value except > ValueError: raise exceptions.ValidationError( > self.error_messages['invalid'], code='invalid', params={'value': value}, ) > except (ValueError, TypeError): raise exceptions.ValidationError( > self.error_messages['invalid'], code='invalid', params={'value': value}, ) > > > Now if I don't perform these changes, I get metadict object has no > attribute pk. Which i resolved by adding try except. Similarly to resolve > validation error i added try except block there. > -- You received this message because you are subscribed to the Google Groups "Django users" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscr...@googlegroups.com. To post to this group, send email to django-users@googlegroups.com. Visit this group at https://groups.google.com/group/django-users. To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/1252fe2e-193d-4ca9-9366-9aecf63da8ad%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.