DRF spectacular not discovering custom auth extension classes - django

when extending a new Token Authentication class from rest_framework_simplejwt.authentication.JWTAuthentication drf-spectacular swagger-ui authorize button disappears and there is no way to add token bearer, I guess when you subclass it goes wrong.
steps to reproduce:
first, create a Django project with rest framework and drf-spectacular and simple jwt installed and configured with documentation guidance. got to /swagger-ui/ and it works fine.
then create a subclass of JWTAuthentication like below:
from rest_framework_simplejwt.authentication import JWTAuthentication as JWTA
class JWTAuthentication(JWTA):
pass
and in your settings:
REST_FRAMEWORK = {
'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
'DEFAULT_AUTHENTICATION_CLASSES': (
'path_to_your_module.JWTAuthentication',
),
}
and now if you go to /swagger-ui/ there is no authorize button!!! how can I fix this?
and I even tried to create an AuthenticationExtension like:
from drf_spectacular.contrib.rest_framework_simplejwt import SimpleJWTScheme
class SimpleJWTTokenUserScheme(SimpleJWTScheme):
target_class = 'path_to_your_module.JWTAuthentication'
but there is no way to register it anywhere nor on the internet nor in the documentation!!
how can I fix authorize button when overriding an Authentication class??
Edit: doing what JPG says and importing extension in settings:
# settings.py
from path.to.custom.extension import SimpleJWTTokenUserScheme
REST_FRAMEWORK = {
'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
'DEFAULT_AUTHENTICATION_CLASSES': (
'path_to_your_module.JWTAuthentication',
),
}
raises exception:
File "/home/hamex/current/spec/env/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/home/hamex/current/spec/env/lib/python3.8/site-packages/django/core/handlers/base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/hamex/current/spec/env/lib/python3.8/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "/home/hamex/current/spec/env/lib/python3.8/site-packages/django/views/generic/base.py", line 70, in view
return self.dispatch(request, *args, **kwargs)
File "/home/hamex/current/spec/env/lib/python3.8/site-packages/rest_framework/views.py", line 509, in dispatch
response = self.handle_exception(exc)
File "/home/hamex/current/spec/env/lib/python3.8/site-packages/rest_framework/views.py", line 469, in handle_exception
self.raise_uncaught_exception(exc)
File "/home/hamex/current/spec/env/lib/python3.8/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
raise exc
File "/home/hamex/current/spec/env/lib/python3.8/site-packages/rest_framework/views.py", line 506, in dispatch
response = handler(request, *args, **kwargs)
File "/home/hamex/current/spec/env/lib/python3.8/site-packages/drf_spectacular/views.py", line 67, in get
return self._get_schema_response(request)
File "/home/hamex/current/spec/env/lib/python3.8/site-packages/drf_spectacular/views.py", line 74, in _get_schema_response
return Response(generator.get_schema(request=request, public=self.serve_public))
File "/home/hamex/current/spec/env/lib/python3.8/site-packages/drf_spectacular/generators.py", line 250, in get_schema
paths=self.parse(request, public),
File "/home/hamex/current/spec/env/lib/python3.8/site-packages/drf_spectacular/generators.py", line 218, in parse
assert isinstance(view.schema, AutoSchema), (
AssertionError: Incompatible AutoSchema used on View <class 'drf_spectacular.views.SpectacularAPIView'>. Is DRF's DEFAULT_SCHEMA_CLASS pointing to "drf_spectacular.openapi.AutoSchema" or any other drf-spectacular compatible AutoSchema?

Update-1
from the doc Where should I put my extensions? / my extensions are not detected
The extensions register themselves automatically. Just be sure that
the python interpreter sees them at least once. To that end, we
suggest creating a PROJECT/schema.py file and importing it in your
PROJECT/__init__.py (same directory as settings.py and urls.py)
with import PROJECT.schema. Please do not import the file in
settings.py as this may potentially lead to cyclic import issues.
Original Answer
It seems a bug with the package itself. You can use the actual class instead of path to class while extending the auth extension
from drf_spectacular.contrib.rest_framework_simplejwt import SimpleJWTScheme
from path.to.custom.jwt.auth import JWTAuthentication
class SimpleJWTTokenUserScheme(SimpleJWTScheme):
target_class = JWTAuthentication
I have created a simple example here, drf-spectacular-example, hope someone will benefit from it!!!

Related

Modifying oscarapi to show some endpoints as public from admin endpoints

What I am trying to achieve is to customize the oscarapi to expose the partner api to be public api instead of just for admin
I have followed the docs on how to customize the api and also did as suggested by Jamie Marshall in
Extending django-oscarapi API ROOT to custom API class
So far I am able to overwrite the root.py file but failing to get oscar see the new urls.py file.
My work so far is as follows
I created a api_customization/views/partner.py file
I created a api_customization/views/root.py file
I tried to extend the urls.py file by creating a api_customization/urls.py file
However, I'm getting the following error
Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 47, in inner response = get_response(request)
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/base.py", line 181, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python3.7/contextlib.py", line 74, in inner return func(*args, **kwds)
File "/usr/local/lib/python3.7/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view return view_func(*args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/django/views/generic/base.py", line 70, in view return self.dispatch(request, *args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/rest_framework/views.py", line 509, in dispatch response = self.handle_exception(exc)
File "/usr/local/lib/python3.7/site-packages/rest_framework/views.py", line 469, in handle_exception self.raise_uncaught_exception(exc)
File "/usr/local/lib/python3.7/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception raise exc
File "/usr/local/lib/python3.7/site-packages/rest_framework/views.py", line 506, in dispatch response = handler(request, *args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/rest_framework/decorators.py", line 50, in handler return func(*args, **kwargs)
File "/code/.../forked_apps/api_customization/views/root.py", line 52, in api_root apis = PUBLIC_APIS(request, format)
File "/code/.../forked_apps/api_customization/views/root.py", line 29, in PUBLIC_APIS ("partners", reverse("partner-list", request=r, format=f)),
File "/usr/local/lib/python3.7/site-packages/rest_framework/reverse.py", line 47, in reverse url = _reverse(viewname, args, kwargs, request, format, **extra)
File "/usr/local/lib/python3.7/site-packages/rest_framework/reverse.py", line 60, in _reverse url = django_reverse(viewname, args=args, kwargs=kwargs, **extra)
File "/usr/local/lib/python3.7/site-packages/django/urls/base.py", line 87, in reverse return iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))
File "/usr/local/lib/python3.7/site-packages/django/urls/resolvers.py", line 685, in _reverse_with_prefix raise NoReverseMatch(msg)
django.urls.exceptions.NoReverseMatch: Reverse for 'partner-list' not found. 'partner-list' is not a valid view function or pattern name.
[09/Jul/2021 21:18:13] "GET /api/ HTTP/1.1" 500 136185
views/partner.py
from oscarapi.utils.loading import get_api_class
from oscar.core.loading import get_model
from rest_framework import generics
PartnerSerializer = get_api_class("serializers.product", "PartnerSerializer")
Partner = get_model("partner", "Partner")
class PublicPartnerList(generics.ListCreateAPIView):
queryset = Partner.objects.all()
serializer_class = PartnerSerializer
urls.py
from django.urls import path
from rest_framework.urlpatterns import format_suffix_patterns
from oscarapi.utils.loading import get_api_class
from oscarapi import urls
PublicPartnerList = get_api_class("views.partner", "PublicPartnerList")
urls.urlpatterns += [
path("partners1/", PublicPartnerList.as_view(), name="partner-list"),
]
urls.urlpatterns += format_suffix_patterns(urls.urlpatterns)
views/root.py
import collections
from django.conf import settings
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.reverse import reverse
__all__ = ("api_root",)
def PUBLIC_APIS(r, f):
return [
# other urls .......
("partners", reverse("partner-list", request=r, format=f)),
]
# remaining file content ......
I need a direction or a hint on how to achieve this
Any help is appreciated
I found a solution to this and might be helpful form someone
I had to do the same steps done for root.py file to get my app recognise the custom urls.py file
So what I did
copy the content of urls.py
modify the file to suit my needs
update my app urls.py file to point to the custom urls.py file of the api
//So from this
path("api/", include("oscarapi.urls")),
//To this
path("api/", include("APP_NAME.forked_apps.api_customization.urls")),

Django Swagger starts failing when include is used in django urls

I am using django rest_framework_swagger for my django project, everything was working fine but when I added some URLs with include method Swagger start giving me 500 internal server error.
I am not sure why this error is coming, I have checked but didn't find anything to fix this error.
I am using:
django 1.11.7
rest_framework_swagger 2.1.2
django rest framework 3.7.3
URLs
from django.conf.urls import url, include
from link_one.views import LinkOneViewSet
from link_two.views import LinkTwoViewSet
schema_view = get_swagger_view(title='My Project APIs')
urlpatterns = [
url(r'^$', schema_view),
url(r'^foo/(?P<foo_id>\w+)/bar/(?P<bar_id>\w+)/link1',
LinkOneViewSet.as_view({'get': 'list'})),
url(r'^foo/(?P<foo_id>\w+)/bar/(?P<bar_id>\w+)/link2',
LinkTwoViewSet.as_view({'get': 'list'})),
url(r'^foo/(?P<foo_id>\w+)/bar/(?P<bar_id>\w+)/link3',
include('link_three.urls'))
]+ static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
Error
[25/Jan/2021 14:03:31] ERROR [django.request.exception:135] Internal Server Error: /
Traceback (most recent call last):
File "C:\Users\myuser\conda_env\lib\site-packages\django\core\handlers\exception.py", line 41, in inner
response = get_response(request)
File "C:\Users\myuser\conda_env\lib\site-packages\django\core\handlers\base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\myuser\conda_env\lib\site-packages\django\core\handlers\base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\myuser\conda_env\lib\site-packages\django\views\decorators\csrf.py", line 58, in wrapped_view
return view_func(*args, **kwargs)
File "C:\Users\myuser\conda_env\lib\site-packages\django\views\generic\base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\myuser\conda_env\lib\site-packages\rest_framework\views.py", line 489, in dispatch
response = self.handle_exception(exc)
File "C:\Users\myuser\conda_env\lib\site-packages\rest_framework\views.py", line 449, in handle_exception
self.raise_uncaught_exception(exc)
File "C:\Users\myuser\conda_env\lib\site-packages\rest_framework\views.py", line 486, in dispatch
response = handler(request, *args, **kwargs)
File "C:\Users\myuser\conda_env\lib\site-packages\rest_framework_swagger\views.py", line 32, in get
schema = generator.get_schema(request=request)
File "C:\Users\myuser\conda_env\lib\site-packages\rest_framework\schemas\generators.py", line 278, in get_schema
links = self.get_links(None if public else request)
File "C:\Users\myuser\conda_env\lib\site-packages\rest_framework\schemas\generators.py", line 316, in get_links
link = view.schema.get_link(path, method, base_url=self.url)
File "C:\Users\myuser\conda_env\lib\site-packages\rest_framework\schemas\inspectors.py", line 179, in get_link
fields += self.get_serializer_fields(path, method)
File "C:\Users\myuser\conda_env\lib\site-packages\rest_framework\schemas\inspectors.py", line 302, in get_serializer_fields
serializer = view.get_serializer()
File "C:\Users\myuser\conda_env\lib\site-packages\rest_framework\generics.py", line 112, in get_serializer
return serializer_class(*args, **kwargs)
TypeError: 'list' object is not callable
After searching a lot and debugging, I have found a solution for this.
The solution is, don't use multiple serializer classes for a ViewSet.
In my one viewset I was doing this and this is what creating the problem.
class FooBarViewset(ModelViewSet):
serializer_class = [DefaultSerializer, BarSerializer, FooSerializer]
But I did not realize that this will cause the error.
Here is Fix that I am using
class FooBarViewset(ModelViewSet):
serializer_class = DefaultSerializer
You can also use the get_serializer method and map serializer class with an action, please check this answer Django rest framework, use different serializers in the same ModelViewSet

why swagger raises unclear error - Django

I have a django rest Backend app, and i use swagger to look and document my apis to the FE.
This worked fine, but I made some changes and now I get this error:
Internal Server Error: /
Traceback (most recent call last):
File "/home/notsoshabby/.local/share/virtualenvs/panda_pitch-UBt5SNMA/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/home/notsoshabby/.local/share/virtualenvs/panda_pitch-UBt5SNMA/lib/python3.7/site-packages/django/core/handlers/base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/home/notsoshabby/.local/share/virtualenvs/panda_pitch-UBt5SNMA/lib/python3.7/site-packages/django/core/handlers/base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/notsoshabby/.local/share/virtualenvs/panda_pitch-UBt5SNMA/lib/python3.7/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "/home/notsoshabby/.local/share/virtualenvs/panda_pitch-UBt5SNMA/lib/python3.7/site-packages/django/views/generic/base.py", line 71, in view
return self.dispatch(request, *args, **kwargs)
File "/home/notsoshabby/.local/share/virtualenvs/panda_pitch-UBt5SNMA/lib/python3.7/site-packages/rest_framework/views.py", line 497, in dispatch
response = self.handle_exception(exc)
File "/home/notsoshabby/.local/share/virtualenvs/panda_pitch-UBt5SNMA/lib/python3.7/site-packages/rest_framework/views.py", line 457, in handle_exception
self.raise_uncaught_exception(exc)
File "/home/notsoshabby/.local/share/virtualenvs/panda_pitch-UBt5SNMA/lib/python3.7/site-packages/rest_framework/views.py", line 468, in raise_uncaught_exception
raise exc
File "/home/notsoshabby/.local/share/virtualenvs/panda_pitch-UBt5SNMA/lib/python3.7/site-packages/rest_framework/views.py", line 494, in dispatch
response = handler(request, *args, **kwargs)
File "/home/notsoshabby/.local/share/virtualenvs/panda_pitch-UBt5SNMA/lib/python3.7/site-packages/rest_framework_swagger/views.py", line 32, in get
schema = generator.get_schema(request=request)
File "/home/notsoshabby/.local/share/virtualenvs/panda_pitch-UBt5SNMA/lib/python3.7/site-packages/rest_framework/schemas/coreapi.py", line 153, in get_schema
links = self.get_links(None if public else request)
File "/home/notsoshabby/.local/share/virtualenvs/panda_pitch-UBt5SNMA/lib/python3.7/site-packages/rest_framework/schemas/coreapi.py", line 140, in get_links
link = view.schema.get_link(path, method, base_url=self.url)
AttributeError: 'AutoSchema' object has no attribute 'get_link'
HTTP GET / 500 [0.15, 127.0.0.1:44214]
/home/notsoshabby/Desktop/panda_pitch/django_project/settings.py
This error is not very clear as the AutoSchema is not a part of my code and the traceback is not showing me where in My code the problem is.
I made too many changes to go one by one and check which one caused that.
Anyone experienced this issue before? Any ideas on how to debug to find which change causes this issue?
I ran into the same issue, the fix is described here: https://www.django-rest-framework.org/community/3.10-announcement/
To summarize, Django Rest Framework 3.10 (released a few days ago) deprecated the CoreAPI based schema generation, and introduced the OpenAPI schema generation in its place. Currently to continue to use django-rest-swagger as is you need to re-enable the CoreAPI schema generation by adding the following config to the settings file:
REST_FRAMEWORK = { ... 'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema' }

Why does Django Rest Framework try to authenticate the request?

I'm encountering an error that can be "resolved" by simply adding to INSTALLED_APPS (without migrate):
'django.contrib.auth',
'django.contrib.contenttypes',
Based on the debug output, it seems this error is occurring because Django Rest Framework is trying to authenticate the request, which requires the Auth app, which requires Permissions and ContentTypes, all of which have been removed. The APIView uses only query_params from request, nothing else. It accepts the global DRF settings as shown:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (),
'DEFAULT_PERMISSION_CLASSES': (),
'DEFAULT_RENDERER_CLASSES': ('common.rest.JSONRenderer',),
'DEFAULT_CONTENT_NEGOTIATION_CLASS': 'common.rest.IgnoreNegotiation',
}
Debug output:
RuntimeError at /mac/pins/
Model class django.contrib.contenttypes.models.ContentType doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.
Request Method: GET
Request URL: http://django/mac/pins/
Django Version: 1.10.5
Python Executable: /home/admin/env/bin/python3.6
Python Version: 3.6.0
Python Path: ['/home/admin/src', '/home/admin/env/bin', '/home/admin/env/lib/python36.zip', '/home/admin/env/lib/python3.6', '/home/admin/env/lib/python3.6/lib-dynload', '/usr/local/lib/python3.6', '/home/admin/env/lib/python3.6/site-packages']
Server time: Fri, 24 Feb 2017 00:54:33 +0000
Installed Applications:
['myapp']
Installed Middleware:
()
Traceback:
File "/home/admin/env/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
39. response = get_response(request)
File "/home/admin/env/lib/python3.6/site-packages/django/core/handlers/base.py" in _legacy_get_response
249. response = self._get_response(request)
File "/home/admin/env/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
187. response = self.process_exception_by_middleware(e, request)
File "/home/admin/env/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
185. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/admin/env/lib/python3.6/site-packages/django/views/decorators/csrf.py" in wrapped_view
58. return view_func(*args, **kwargs)
File "/home/admin/env/lib/python3.6/site-packages/django/views/generic/base.py" in view
68. return self.dispatch(request, *args, **kwargs)
File "/home/admin/env/lib/python3.6/site-packages/rest_framework/views.py" in dispatch
483. response = self.handle_exception(exc)
File "/home/admin/env/lib/python3.6/site-packages/rest_framework/views.py" in handle_exception
443. self.raise_uncaught_exception(exc)
File "/home/admin/env/lib/python3.6/site-packages/rest_framework/views.py" in dispatch
471. self.initial(request, *args, **kwargs)
File "/home/admin/env/lib/python3.6/site-packages/rest_framework/views.py" in initial
393. self.perform_authentication(request)
File "/home/admin/env/lib/python3.6/site-packages/rest_framework/views.py" in perform_authentication
319. request.user
File "/home/admin/env/lib/python3.6/site-packages/rest_framework/request.py" in __getattribute__
379. return super(Request, self).__getattribute__(attr)
File "/home/admin/env/lib/python3.6/site-packages/rest_framework/request.py" in user
196. self._authenticate()
File "/home/admin/env/lib/python3.6/site-packages/rest_framework/request.py" in _authenticate
352. self._not_authenticated()
File "/home/admin/env/lib/python3.6/site-packages/rest_framework/request.py" in _not_authenticated
363. if api_settings.UNAUTHENTICATED_USER:
File "/home/admin/env/lib/python3.6/site-packages/rest_framework/settings.py" in __getattr__
220. val = perform_import(val, attr)
File "/home/admin/env/lib/python3.6/site-packages/rest_framework/settings.py" in perform_import
163. return import_from_string(val, setting_name)
File "/home/admin/env/lib/python3.6/site-packages/rest_framework/settings.py" in import_from_string
177. module = import_module(module_path)
File "/home/admin/env/lib/python3.6/importlib/__init__.py" in import_module
126. return _bootstrap._gcd_import(name[level:], package, level)
File "/home/admin/env/lib/python3.6/site-packages/django/contrib/auth/models.py" in <module>
6. from django.contrib.contenttypes.models import ContentType
File "/home/admin/env/lib/python3.6/site-packages/django/contrib/contenttypes/models.py" in <module>
138. class ContentType(models.Model):
File "/home/admin/env/lib/python3.6/site-packages/django/db/models/base.py" in __new__
113. "INSTALLED_APPS." % (module, name)
Exception Type: RuntimeError at /mac/pins/
Exception Value: Model class django.contrib.contenttypes.models.ContentType doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.
Why is it trying to authenticate the request? How can I stop it?
It's not trying to authenticate the request. You don't have any authenticators so it skipped over an empty tuple and went to:
352. self._not_authenticated()
However the unauthenticated user object in rest framework defaults to this:
# Authentication
'UNAUTHENTICATED_USER': 'django.contrib.auth.models.AnonymousUser',
So maybe you'll need to provide your own unauthenticated user model, if you don't want to pull in django.contrib.auth.

Assiging permissions with guardian's shortcut assign_perm results in 'NoneType' object has no attribute 'objects'

I have two applications in my Django project, let's assume it's appA and appB. Those applications are installed from external packages via pip install. Both of them have additional permissions in their models:
appA has got:
class Meta:
permissions = (
('clone_poll', 'Can clone poll'),
('close_poll', 'Can close poll'),
('viewresults_poll', 'Can view poll results'),
)
appB has got:
class Meta:
permissions = (
('viewresults_meeting', 'Can view meeting results'),
)
I installed both applications in my project and tried to create some instances of models their have. Everything works fine(object is created and saved to DB) until permission assign step, where the following error occurred:
Traceback (most recent call last):
File "/home/polls/pythonPolls/lib/python2.7/site-packages/django/core/handlers/base.py", line 114, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/polls/pythonPolls/lib/python2.7/site-packages/django/contrib/auth/decorators.py", line 22, in _wrapped_view
return view_func(request, *args, **kwargs)
File "/home/polls/pythonPolls/lib/python2.7/site-packages/polls/views.py", line 529, in clone_poll
initial_dict=initial)(request, kwargs=kwa)
File "/home/polls/pythonPolls/lib/python2.7/site-packages/django/views/generic/base.py", line 69, in view
return self.dispatch(request, *args, **kwargs)
File "/home/polls/pythonPolls/lib/python2.7/site-packages/django/contrib/formtools/wizard/views.py", line 236, in dispatch
response = super(WizardView, self).dispatch(request, *args, **kwargs)
File "/home/polls/pythonPolls/lib/python2.7/site-packages/django/views/generic/base.py", line 87, in dispatch
return handler(request, *args, **kwargs)
File "/home/polls/pythonPolls/lib/python2.7/site-packages/django/contrib/formtools/wizard/views.py", line 297, in post
return self.render_done(form, **kwargs)
File "/home/polls/pythonPolls/lib/python2.7/site-packages/django/contrib/formtools/wizard/views.py", line 350, in render_done
done_response = self.done(final_form_list, **kwargs)
File "/home/polls/pythonPolls/lib/python2.7/site-packages/polls/views.py", line 203, in done
assign_perm('polls.change_poll', self.request.user, poll_obj)
File "/home/polls/pythonPolls/lib/python2.7/site-packages/guardian/shortcuts.py", line 91, in assign_perm
return model.objects.assign_perm(perm, user, obj)
File "/home/polls/pythonPolls/lib/python2.7/site-packages/guardian/managers.py", line 41, in assign_perm
obj_perm, created = self.get_or_create(**kwargs)
File "/home/polls/pythonPolls/lib/python2.7/site-packages/django/db/models/manager.py", line 154, in get_or_create
return self.get_queryset().get_or_create(**kwargs)
File "/home/polls/pythonPolls/lib/python2.7/site-packages/django/db/models/query.py", line 380, in get_or_create
obj.save(force_insert=True, using=self.db)
File "/home/polls/pythonPolls/lib/python2.7/site-packages/guardian/models.py", line 44, in save
content_type = ContentType.objects.get_for_model(self.content_object)
AttributeError: 'NoneType' object has no attribute 'objects'
I inspected the exact place of occurring the error, it is in django-guardian internal. It seems that garbage collector cleaned local context, setting all imports to None:
'UserObjectPermissionManager': None,
'__file__': None,
'user_model_label': None,
'__name__': None,
'GroupObjectPermissionManager': None,
'ContentType': None,
'settings': None,
'Permission': None,
'GroupObjectPermissionBase': None,
'BaseObjectPermission': None,
'UserObjectPermissionBase': None
What is more, when I remove one of the applications e.g. appA from INSTALLED_APPS, the other works fine i.e. all permissions are set.
I have no idea what is the origin of this problem, if it's in my apps, in guardian or in completely other application?
After a few days of struggling with this problem I finally found the solution, and the real origin of this problem.
First of all I've been using Django 1.6.10. In both applications I have registered handlers for user_logged_in signals. I put the proper functions and bindings(user_logged_in.connect(handler)) into the file called signals.py in both apps. Then signals.py was imported in __init__.py, to make the signals connection work. There was also another dependance on the models.py in one of the files, which was also imported into signals.py- this was done in one of the apps. Getting to the point, the problem was circular imports in one of the app. The solution I found to work was to move signals.py contents to models.py, remove signals imports from __init__.py.