I can't see DRF api confirm browser - django-rest-framework

i want to see
But my browser is
I checked the api operation through postman.
i have no idea what is the problem..
I don't think there's a problem with the code
This is my code
project folder urls.py
url(r'^', include('django.contrib.auth.urls')),
url(r'^rest-auth/', include('rest_auth.urls')),
url(r'^rest-auth/registration/', include('rest_auth.registration.urls')),
url(r'^account/', include('allauth.urls')),
url(r'^accounts-rest/registration/account-confirm-email/(?P<key>.+)/$',
confirm_email, name='account_confirm_email'),
settings.py
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
# 'rest_framework.permissions.IsAuthenticated',
'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly',
),
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
],
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
],
}
REST_AUTH_SERIALIZERS = {
'USER_DETAILS_SERIALIZER': 'accounts.serializers.UserSerializer',
}
Any hint would be very very very appreciated :)

Add rest_framework.renderers.BrowsableAPIRenderer to default renderer classes of the REST_FRAMEWORK settings.
...
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
]
...

Related

How to differentiate my views in DRF swagger (yasg)?

I have an api made with djangorestframework and I want to add a swagger. It works well. In my api I have some views that require authentication with Basic or JWT so I set this up in my settings. The problem is that in my swagger gui I do not manage to tell which view is not requiring authentication. Do you know how to do that.
#api/urls.py
from drf_yasg import openapi
schema_view = get_schema_view(
openapi.Info(
title="Snippets API",
default_version='v1',
description="Test description",
terms_of_service="https://www.google.com/policies/terms/",
contact=openapi.Contact(email="contact#snippets.local"),
license=openapi.License(name="BSD License"),
),
public=True,
permission_classes=[permissions.AllowAny],
)
urlpatterns = [
path('mesures/', views.get_all),
path('mesure-add/', views.add_mesure),
path('token/', TokenObtainPairView.as_view(), name='obtain_tokens'),
path('token/refresh/', TokenRefreshView.as_view(), name='refresh_token'),
path('api-auth/', include('rest_framework.urls')),
path('register/', views.register_user),
path('redoc/', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
]
In my settings.py
# in my settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework_simplejwt.authentication.JWTAuthentication',
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
]
}
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(days=int(os.getenv("TOKEN_DAYS_LIFE"))),
}
SWAGGER_SETTINGS = {
'SECURITY_DEFINITIONS': {
'Basic': {
'type': 'basic'
},
'Bearer': {
'type': 'apiKey',
'name': 'Authorization',
'in': 'header'
}
}
}
In my views.py
#views.py
#swagger_auto_schema(methods=['post'], request_body=MesureSerializer)
#api_view(['POST'])
#permission_classes([IsAuthenticated])
def add_mesure(request):
serializer = MesureSerializer(data=request.data, context={'request':request})
# this is to provide the user automatically from token auth
# no need to provide it from the post request
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
else:
return Response(serializer._errors)
#swagger_auto_schema(methods=['post'], request_body=UserSerializer)
#api_view(['POST'])
def register_user(request):
serializer = UserSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
as you can see my view register_user should not show a authentication in my swagger but this is not the case.
It is ok, I just needed to use the security=[] in #swagger_auto_schema for the specific view I want to tell there is no authentication required.
#swagger_auto_schema(methods=['post'], request_body=UserSerializer, security=[])

how to turn jwt settings into simplejwt settings?

Here is my problem. I have a project that used rest_framework_JWT like this
JWT_AUTH = {
"JWT_VERIFY": True,
"JWT_VERIFY_EXPIRATION": True,
"JWT_EXPIRATION_DELTA": datetime.timedelta(days=30),
"JWT_AUTH_HEADER_PREFIX": "Bearer",
"JWT_AUTH_COOKIE": "x-access-token",
}
but now i want to change from JWT to rest_framework_simpleJWT, what is the corresponding fields should i change to in simplejwt? Is this right?
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
'REFRESH_TOKEN_LIFETIME': timedelta(days=5),
'AUTH_HEADER_TYPES': ('Bearer',),
'AUTH_HEADER_NAME': 'HTTP_X_ACCESS_TOKEN',
}
I think you need to add and change the settings in the INSTALLED_APPS and REST_FRAMEWORK.DEFAULT_AUTHENTICATION_CLASSES.
In settings.py file,
INSTALLED_APPS = [
...
'rest_framework_simplejwt'
]
...
REST_FRAMEWORK = {
...
'DEFAULT_AUTHENTICATION_CLASSES': {
'rest_framework_simplejwt.authentication.JWTAuthentication'
}
...
}
Here is the sample configuration settings you can set:
# Django project settings.py
from datetime import timedelta
...
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
'ROTATE_REFRESH_TOKENS': False,
'BLACKLIST_AFTER_ROTATION': False,
'UPDATE_LAST_LOGIN': False,
'ALGORITHM': 'HS256',
'SIGNING_KEY': SECRET_KEY,
'VERIFYING_KEY': None,
'AUDIENCE': None,
'ISSUER': None,
'JWK_URL': None,
'LEEWAY': 0,
'AUTH_HEADER_TYPES': ('Bearer',),
'AUTH_HEADER_NAME': 'HTTP_AUTHORIZATION',
'USER_ID_FIELD': 'id',
'USER_ID_CLAIM': 'user_id',
'USER_AUTHENTICATION_RULE': 'rest_framework_simplejwt.authentication.default_user_authentication_rule',
'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
'TOKEN_TYPE_CLAIM': 'token_type',
'TOKEN_USER_CLASS': 'rest_framework_simplejwt.models.TokenUser',
'JTI_CLAIM': 'jti',
'SLIDING_TOKEN_REFRESH_EXP_CLAIM': 'refresh_exp',
'SLIDING_TOKEN_LIFETIME': timedelta(minutes=5),
'SLIDING_TOKEN_REFRESH_LIFETIME': timedelta(days=1),
}
Link to its documentation is here: documentation
Also, this is a boiler plate code that you can also plug and play in your project for Django authentication with simplejwt.
You can simply clone it and add above configuration in settings.py file there.
Boiler plate code for django simplejwt authentication

Postman asking for login credentials even though I am using a Bearer token

I have a Django Rest Framework backend that uses a Bearer token to authenticate a user for all APIS, while testing it on POSTMAN, it displays a Django admin login form
link to POSTMAN screenshot
I don't understand why it's asking me to authenticate as an admin on POSTMAN.
As requested I've added urls.py for base and user:
Base urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('', admin.site.urls),
path('user/v1/', include(('user.v1.urls', 'user'), namespace='user_v1')),
path('second-opinion/v1/', include(('second_opinion.v1.urls', 'second-opinion'), namespace='second-opinion_v1')),
path('utils/v1/', include(('utils.urls', 'utils'), namespace='utils_v1')),
]
User urls.py
from django.urls import path
from django.conf.urls import url, include
from rest_framework import routers
from user.v1.views import UserView, NotificationView, PhysicianDetailView, PhysicianProfileRequestsView, \
ProfileInviteView, create_cognito_user, get_physician_detail
router = routers.DefaultRouter()
router.register(r'profile', UserView, basename='profile')
router.register(r'notification', NotificationView, basename='notification')
router.register(r'physician-detail', PhysicianDetailView, basename='physician-detail')
router.register(r'profile-request', PhysicianProfileRequestsView, basename='profile-request')
router.register(r'profile-invite', ProfileInviteView, basename='profile-invite')
urlpatterns = [
url(r'^', include(router.urls)),
path(r'create_default_user/', create_cognito_user),
path(r'physician/detail/<int:user_id>', get_physician_detail)
]
Rest Framework dictionary:
REST_FRAMEWORK = {
'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.NamespaceVersioning',
'DEFAULT_PERMISSION_CLASSES': ['rest_framework.permissions.IsAuthenticated',],
'DEFAULT_PAGINATION_CLASS': 'utils.pagination.CustomPagination',
'DEFAULT_AUTHENTICATION_CLASSES': (
'django_cognito_jwt.JSONWebTokenAuthentication',
),
'PAGE_SIZE': 10,
'EXCEPTION_HANDLER': 'utils.custom_exception_handler.custom_exception_handler'
}
In your Base urls.py can you try moving path('', admin.site.urls), at the end of urlpatterns list instead of the very first.
Because django resolves urls in sequence and due to '' in your path for admin sites all your urls are resolving to admin page.

Problem with the error * A server error occurred. Please contact the administrator * django rest framework

I am trying to test some basic backed fonctionnalities but I seem to have this error A server error occurred. Please contact the administrator while trying to connect to the localhost http://127.0.0.1:8000 or http://127.0.0.1:8000/sise/.
At first I had this error showing django.core.exceptions.ImproperlyConfigured: The included URLconf 'Dashboard_sise.urls' does not appear to have any patterns in it. If you see valid patterns in the file then the issue is probably caused by a circular import. but After I commented this line in the settings file ROOT_URLCONF = 'Dashboard_sise.urls' the error changed into A server error occurred. Please contact the administrator.
Can anyone please help me figure this problem out, I already tried changing the urlpatterns in the urls.py files but it didn't work, I also tried manipulating the MIDDLEWARE section in the settings file but nothing changed.
This is the Dashboard_sise.urls code
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('admin/', admin.sites.urls),
path('sise/', include('Dashboard.urls')),
]
This is the Dashboard.urls code
from rest_framework.routers import DefaultRouter
from Dashboard.views import *
router = DefaultRouter()
router.register(r'accee', AcceeViewSet, basename='accee')
router.register(r'rapport', RapportViewSet, basename='rapport')
router.register(r'prise_fonction', PointageUtilisateurViewSet, basename='prise_fonction')
urlPatterns = router.urls
and finally the settings file
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
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/3.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '+f-#$j*(-8^*7ijk#6_hpki#)am4e%na6ttp)54#-ddcs0#fgy'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = ['*']
PREPEND_WWW = False
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'corsheaders',
'Dashboard',
'frontend'
]
MIDDLEWARE = [
'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',
'corsheaders.middleware.CorsMiddleware',
]
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')]
,
'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 = 'Dashboard_sise.wsgi.application'
'''ROOT_URLCONF = 'Dashboard_sise.urls'''
# Database
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'MainCourante',
'USER': 'postgres',
'PASSWORD': 'root',
'HOST': 'localhost',
'PORT': '5432',
}
}
# Password validation
# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/3.0/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
APPEND_SLASH = False
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.0/howto/static-files/
STATIC_URL = '/static/'
'''REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
'rest_framework.authentification.BasicAuthentification'
'rest_framework.authentification.SessionAuthentification'
# 'rest_framework.permissions.IsAuthentificated'
# 'rest_framework.permissions.AllowAny'
)
}'''
CORS_ORIGIN_ALLOW_ALL = True # If this is used then `CORS_ORIGIN_WHITELIST` will not have any effect
Thank you in adavance
I will answer this in case someone faced the same bug. I had a problem with the database structure .. The models implemented in the models.py file and the database created didn't match so it kept showing me this error ... once I fixed the models.py file it all worked well
Maybe this was the cause.
urlPatterns = router.urls
its usually urlpatterns.

Can't resolve all parameters for UIRouter: (?, ?)

I am using angular2 and uirouter for routing. I have successfully implemented uirouter module in application.But the problem arises when i try to test my application. Where i am using karma, Jasmin and initiating it using npm test. but encountered with ERROR:Can't resolve all parameters for UIRouter: (?, ?).
I have imported "UIRouter" in *.spec.ts file and added it in providers array as below.
import { UIRouterModule } from '#uirouter/angular';
import { UIRouter } from "#uirouter/core";
describe('Footer Menus', () => {
let footerMenuBlServiceRef:FooterMenuBLService;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [],
declarations: [],
providers: [UIRouter],
})
.compileComponents();
}));
But no luck. Any help will be appreciated.
Solved it !!!
Just remove the UIRouter from providers array but keep the import statement for it. and yes its working.
On last friday, I finally found a way to make it work. It is not a clean way to do it but it is working, at least.
I reimport the UIRouter.forRoot with the states of my feature module and I provide the APP_BASE_HREF value for the Root Provider of UIRouter.
Here is my BeforeEach :
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
HomeComponent,
HomeCardComponent
],
imports: [
AppMaterialModule,
// Always import root UIRouter module when testing a component including routing
UIRouterModule.forRoot({states: HOME_STATES})
],
providers: [
// Also, include the base href value when testing a component including routing
{provide: APP_BASE_HREF, useValue: '/'}
],
}).compileComponents();
}));
If you know a better way, I would be happy to know! :)
The UI-Router source can be of some help. This is what worked for me:
import { UIRouterModule } from '#uirouter/angular';
...
TestBed.configureTestingModule({
...
imports: [UIRouterModule.forRoot({ useHash: true })],
})

Resources