Mongo related issue in Django

136 views
Skip to first unread message

Ashish Khatkar

unread,
Jun 23, 2015, 1:36:03 PM6/23/15
to django-d...@googlegroups.com
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.

Tim Graham

unread,
Jun 23, 2015, 1:50:11 PM6/23/15
to django-d...@googlegroups.com
It's difficult to tell what the issue is without seeing all you code, but "is this is a bug?" questions are more suited for the django-users mailing list. A good first step in testing your "fix" is to see if Django's test suite passes afterwards. I suspect you'll see some test failures with the changes you proposed.

Ashish Khatkar

unread,
Jun 23, 2015, 2:53:45 PM6/23/15
to django-d...@googlegroups.com
Hi,
This is 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

For the full list of settings and their values, see
"""

# 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

# 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

# DATABASES = {
#     'default': {
#         'ENGINE': 'django.db.backends.sqlite3',
#         'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
#     }
# }


# Internationalization

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'Asia/Kolkata'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)

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 :
@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:
           return int(value)
       except ValueError:
           return value
       except TypeError:
           raise exceptions.ValidationError(
               self.error_messages['invalid'],
               code='invalid',
               params={'value': value},
           )

Changes I did in
django/db/models/fields/__init__.py
try:
       request.session[SESSION_KEY] = user._meta.pk.value_to_string(user)
   except Exception:
       request.session[SESSION_KEY] = user.id


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.

Tim Graham

unread,
Jun 23, 2015, 3:29:48 PM6/23/15
to django-d...@googlegroups.com
Sorry, but that doesn't help as I have no experience with mongoengine. As I said, if you want further help, you might find it on the django-users mailing list but I would  check mongoengine support for Django. It's not so clear they are working on it now.

https://github.com/MongoEngine/mongoengine/blob/master/docs/django.rst


On Tuesday, June 23, 2015 at 2:53:45 PM UTC-4, Ashish Khatkar wrote:
Hi,
...

Ashish Khatkar

unread,
Jun 23, 2015, 4:16:12 PM6/23/15
to django-d...@googlegroups.com
Sure, I will ask this question in Django users also. Though I ran the test suite after fixing this and all tests passed without any error.
Reply all
Reply to author
Forward
0 new messages