marazmiki / django-ulogin

Plug a social authentication feature to your Django application easy!
https://django-ulogin.readthedocs.io/ru/latest/
MIT License
26 stars 19 forks source link

Error in django admin then trying to delete user with ULoginUser assigned #43

Closed shot131 closed 4 years ago

shot131 commented 4 years ago

TypeError str returned non-string (type User)

I think this is because https://github.com/marazmiki/django-ulogin/blob/master/django_ulogin/models.py#L43 return non string value.

Django 3.0.4 and Python 3.8

marazmiki commented 4 years ago

Hello Alex,

According to the code, we use six there. It's a polyfill library that allows using the same code both on Python 2.x and 3.x. The text_type function always returns string type depending on the python version, i.e. it would be str on Python 3.x and unicode on Python 2.x.

Thus, this method could not return a non-string value.

But let's imagine what happens if text_type could not convert an input object into str type. Suppose, we get TypeError exception. As I can see in the code, the __str__() method of the model tries to convert a related User model into a string. If it fails, maybe your User model has not the __str__() method implemented?

Anyway, could you provide a stack trace?

shot131 commented 4 years ago

Traceback

Environment:

Request Method: GET Request URL: http://localhost:8080/lauda-admin/users/user/2/delete/

Django Version: 3.0.4 Python Version: 3.8.1 Installed Applications: ['ckeditor', 'ckeditor_uploader', 'adminsortable2', 'polymorphic_tree', 'polymorphic', 'mptt', 'embed_video', 'django_admin_listfilter_dropdown', 'easy_thumbnails', 'rosetta', 'multiselectfield', 'nested_admin', 'admin_interface', 'colorfield', 'rangefilter', 'admin_auto_filters', 'widget_tweaks', 'django_ulogin', 'phonenumber_field', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'django.contrib.sites', 'users.apps.UsersConfig', 'pages.apps.PagesConfig', 'places.apps.PlacesConfig', 'gallery.apps.GalleryConfig', 'yandex_maps.apps.YandexMapsConfig', 'meet_places.apps.MeetPlacesConfig', 'reviews.apps.ReviewsConfig', 'payways.apps.PaywaysConfig', 'tours.apps.ToursConfig', 'questions.apps.QuestionsConfig', 'discounts.apps.DiscountsConfig', 'orders.apps.OrdersConfig', 'seo_filter.apps.SeoFilterConfig', 'auth_extended.apps.AuthExtendedConfig', 'ajax_forms.apps.AjaxFormsConfig'] Installed Middleware: ['django.middleware.cache.UpdateCacheMiddleware', 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.locale.LocaleMiddleware', 'django.middleware.cache.FetchFromCacheMiddleware']

Traceback (most recent call last): File "/home/vagrant/.local/share/virtualenvs/vagrant-gKDsaKU3/lib/python3.8/site-packages/django/core/handlers/exception.py", line 34, in inner response = get_response(request) File "/home/vagrant/.local/share/virtualenvs/vagrant-gKDsaKU3/lib/python3.8/site-packages/django/core/handlers/base.py", line 115, in _get_response response = self.process_exception_by_middleware(e, request) File "/home/vagrant/.local/share/virtualenvs/vagrant-gKDsaKU3/lib/python3.8/site-packages/django/core/handlers/base.py", line 113, in _get_response response = wrapped_callback(request, *callback_args, callback_kwargs) File "/home/vagrant/.local/share/virtualenvs/vagrant-gKDsaKU3/lib/python3.8/site-packages/django/contrib/admin/options.py", line 607, in wrapper return self.admin_site.admin_view(view)(*args, *kwargs) File "/home/vagrant/.local/share/virtualenvs/vagrant-gKDsaKU3/lib/python3.8/site-packages/django/utils/decorators.py", line 130, in _wrapped_view response = view_func(request, args, kwargs) File "/home/vagrant/.local/share/virtualenvs/vagrant-gKDsaKU3/lib/python3.8/site-packages/django/views/decorators/cache.py", line 44, in _wrapped_view_func response = view_func(request, *args, kwargs) File "/home/vagrant/.local/share/virtualenvs/vagrant-gKDsaKU3/lib/python3.8/site-packages/django/contrib/admin/sites.py", line 231, in inner return view(request, *args, *kwargs) File "/home/vagrant/.local/share/virtualenvs/vagrant-gKDsaKU3/lib/python3.8/site-packages/django/utils/decorators.py", line 43, in _wrapper return bound_method(args, kwargs) File "/home/vagrant/.local/share/virtualenvs/vagrant-gKDsaKU3/lib/python3.8/site-packages/django/utils/decorators.py", line 130, in _wrapped_view response = view_func(request, *args, **kwargs) File "/home/vagrant/.local/share/virtualenvs/vagrant-gKDsaKU3/lib/python3.8/site-packages/django/contrib/admin/options.py", line 1831, in delete_view return self._delete_view(request, object_id, extra_context) File "/home/vagrant/.local/share/virtualenvs/vagrant-gKDsaKU3/lib/python3.8/site-packages/django/contrib/admin/options.py", line 1852, in _delete_view deleted_objects, model_count, perms_needed, protected = self.get_deleted_objects([obj], request) File "/home/vagrant/.local/share/virtualenvs/vagrant-gKDsaKU3/lib/python3.8/site-packages/django/contrib/admin/options.py", line 1826, in get_deleted_objects return get_deleted_objects(objs, request, self.admin_site) File "/home/vagrant/.local/share/virtualenvs/vagrant-gKDsaKU3/lib/python3.8/site-packages/django/contrib/admin/utils.py", line 151, in get_deleted_objects to_delete = collector.nested(format_callback) File "/home/vagrant/.local/share/virtualenvs/vagrant-gKDsaKU3/lib/python3.8/site-packages/django/contrib/admin/utils.py", line 211, in nested roots.extend(self._nested(root, seen, format_callback)) File "/home/vagrant/.local/share/virtualenvs/vagrant-gKDsaKU3/lib/python3.8/site-packages/django/contrib/admin/utils.py", line 195, in _nested children.extend(self._nested(child, seen, format_callback)) File "/home/vagrant/.local/share/virtualenvs/vagrant-gKDsaKU3/lib/python3.8/site-packages/django/contrib/admin/utils.py", line 197, in _nested ret = [format_callback(obj)] File "/home/vagrant/.local/share/virtualenvs/vagrant-gKDsaKU3/lib/python3.8/site-packages/django/contrib/admin/utils.py", line 126, in format_callback no_edit_link = '%s: %s' % (capfirst(opts.verbose_name), obj)

Exception Type: TypeError at /lauda-admin/users/user/2/delete/ Exception Value: str returned non-string (type User)

In django 3 releaset notes:

django.utils.six - Remove usage of this vendored library or switch to six.

https://docs.djangoproject.com/en/3.0/releases/3.0/#removed-private-python-2-compatibility-apis

marazmiki commented 4 years ago

Could you also provide variable values from the latest frame of the stack trace? I mean, what obj is. And which fields it has. Are you sure, obj has __str__() method defined?

And please, do not doubt about six was dropped from django. Take a look here, as you can see, we use six only when we can import it. If we cannot, we just use a mock function text_type() we defined in the module.

shot131 commented 4 years ago

My model extends django.contrib.auth.models.AbstractUser it has __str__ method returns username field. And error apears only then my User model has ULoginUser defined.

Also if i change ULoginUser __str__ method to return str() not text_type() error disappear.

Maybe https://github.com/marazmiki/django-ulogin/blob/master/django_ulogin/compat.py#L11 returns User object if six import failed?

marazmiki commented 4 years ago

Oh, you're right!

marazmiki commented 4 years ago

Will fix shortly

shot131 commented 4 years ago

Thank you, great component.

marazmiki commented 4 years ago

Just bumped 1.0.4. Please update and confirm the bug is gone ;)

shot131 commented 4 years ago

Yes, all works fine, thank you.

marazmiki commented 4 years ago

:ok_hand: