Updated version
This commit is contained in:
parent
cd8d7b0e2c
commit
49eb16d0ac
Binary file not shown.
Binary file not shown.
0
admin_api/api/__init__.py
Normal file
0
admin_api/api/__init__.py
Normal file
BIN
admin_api/api/__pycache__/__init__.cpython-310.pyc
Normal file
BIN
admin_api/api/__pycache__/__init__.cpython-310.pyc
Normal file
Binary file not shown.
BIN
admin_api/api/__pycache__/urls.cpython-310.pyc
Normal file
BIN
admin_api/api/__pycache__/urls.cpython-310.pyc
Normal file
Binary file not shown.
BIN
admin_api/api/__pycache__/views.cpython-310.pyc
Normal file
BIN
admin_api/api/__pycache__/views.cpython-310.pyc
Normal file
Binary file not shown.
0
admin_api/api/serilaizer.py
Normal file
0
admin_api/api/serilaizer.py
Normal file
15
admin_api/api/urls.py
Normal file
15
admin_api/api/urls.py
Normal file
@ -0,0 +1,15 @@
|
||||
from django.urls import path
|
||||
from . import views
|
||||
from .views import MyTokenObtainPairView
|
||||
|
||||
from rest_framework_simplejwt.views import (
|
||||
TokenRefreshView,
|
||||
)
|
||||
|
||||
urlpatterns = [
|
||||
path('', views.getRoutes, name="routes"),
|
||||
|
||||
path('token/', MyTokenObtainPairView.as_view(), name='token_obtain_pair'),
|
||||
path('token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
|
||||
|
||||
]
|
29
admin_api/api/views.py
Normal file
29
admin_api/api/views.py
Normal file
@ -0,0 +1,29 @@
|
||||
from django.http import JsonResponse
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.decorators import api_view
|
||||
|
||||
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
|
||||
from rest_framework_simplejwt.views import TokenObtainPairView
|
||||
|
||||
class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
|
||||
@classmethod
|
||||
def get_token(cls, user):
|
||||
token = super().get_token(user)
|
||||
|
||||
# Add custom claims
|
||||
token['username'] = user.username
|
||||
# ...
|
||||
|
||||
return token
|
||||
|
||||
class MyTokenObtainPairView(TokenObtainPairView):
|
||||
serializer_class = MyTokenObtainPairSerializer
|
||||
|
||||
@api_view(['GET'])
|
||||
def getRoutes(request):
|
||||
routes = [
|
||||
'/api/token',
|
||||
'/api/token/refresh',
|
||||
]
|
||||
|
||||
return Response(routes)
|
@ -25,6 +25,8 @@ urlpatterns = [
|
||||
|
||||
path('pre-process/', views.preprocess, name='pre-process'),
|
||||
|
||||
path('api/', include('admin_api.api.urls')),
|
||||
|
||||
path('login/', views.loginPage, name='login'),
|
||||
path('logout/', views.logoutPage, name='logout'),
|
||||
]
|
@ -10,16 +10,18 @@ from django.views.decorators.csrf import csrf_exempt
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
from rest_framework.decorators import api_view
|
||||
from rest_framework.decorators import api_view, permission_classes
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from rest_framework.response import Response
|
||||
from django.db.models import Max
|
||||
import shutil
|
||||
from django.contrib.auth import authenticate, login, logout
|
||||
from django.contrib import messages
|
||||
|
||||
|
||||
from .preprocessData import PreprocessData
|
||||
# Create your views here.
|
||||
|
||||
@permission_classes([IsAuthenticated])
|
||||
class LevelViewSet(viewsets.ModelViewSet):
|
||||
queryset = Level.objects.all()
|
||||
serializer_class = LevelSerializer
|
||||
@ -35,6 +37,10 @@ class NewContentTrackerViewSet(viewsets.ModelViewSet):
|
||||
|
||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||
|
||||
# ################################################################
|
||||
# #######################Contents#################################
|
||||
# ################################################################
|
||||
|
||||
@csrf_exempt
|
||||
@api_view(['GET'])
|
||||
def contentList(request):
|
||||
@ -202,11 +208,11 @@ def levelDelete(request):
|
||||
|
||||
haveToPreProcess(data['id'], data['levelNumber'], 'No', 'LevelDeleted')
|
||||
|
||||
return Response('Item successfully deleted!')
|
||||
return Response('')
|
||||
|
||||
|
||||
# ################################################################
|
||||
# #######################Standards###################################
|
||||
# #######################Standards################################
|
||||
# ################################################################
|
||||
|
||||
@csrf_exempt
|
||||
@ -254,7 +260,7 @@ def standardDelete(request):
|
||||
return Response('Item successfully deleted!')
|
||||
|
||||
# ################################################################
|
||||
# #######################pre-process###################################
|
||||
# #######################pre-process##############################
|
||||
# ################################################################
|
||||
@csrf_exempt
|
||||
@api_view(['POST'])
|
||||
@ -265,7 +271,7 @@ def preprocess(request):
|
||||
return Response('Procssed successfully')
|
||||
|
||||
# ################################################################
|
||||
# #######################Login/out###################################
|
||||
# #######################Authentication###########################
|
||||
# ################################################################
|
||||
|
||||
def loginPage(request):
|
||||
@ -275,6 +281,10 @@ def loginPage(request):
|
||||
def logoutPage(request):
|
||||
pass
|
||||
|
||||
# ################################################################
|
||||
# ################################################################
|
||||
# ################################################################
|
||||
|
||||
def filePath(level_input, standard_input):
|
||||
standards_dir = os.path.join(BASE_DIR, 'static/data/')
|
||||
file_path = ''
|
||||
|
BIN
db.sqlite3
BIN
db.sqlite3
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -11,6 +11,9 @@ https://docs.djangoproject.com/en/4.1/ref/settings/
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
from datetime import timedelta
|
||||
from pathlib import Path
|
||||
import os
|
||||
|
||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||
@ -30,9 +33,9 @@ ALLOWED_HOSTS = []
|
||||
# In this particular case, it is allowing cross-origin requests from
|
||||
# the specified origin http://localhost:3000, which is the default origin
|
||||
# for a locally served React application during development.
|
||||
CORS_ALLOWED_ORIGINS = [
|
||||
'http://localhost:3000',
|
||||
]
|
||||
#CORS_ALLOWED_ORIGINS = [
|
||||
# 'http://localhost:3000',
|
||||
#]
|
||||
|
||||
CORS_ORIGIN_ALLOW_ALL = True
|
||||
CORS_ALLOW_CREDENTIALS = True
|
||||
@ -47,13 +50,65 @@ INSTALLED_APPS = [
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
'rest_framework',
|
||||
'rest_framework_simplejwt.token_blacklist',
|
||||
'django_filters',
|
||||
'search_tfidf',
|
||||
'admin_api',
|
||||
'user_auth',
|
||||
'corsheaders',
|
||||
]
|
||||
|
||||
REST_FRAMEWORK = {
|
||||
'DEFAULT_AUTHENTICATION_CLASSES': (
|
||||
|
||||
'rest_framework_simplejwt.authentication.JWTAuthentication',
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
||||
SIMPLE_JWT = {
|
||||
"ACCESS_TOKEN_LIFETIME": timedelta(minutes=5),
|
||||
"REFRESH_TOKEN_LIFETIME": timedelta(days=90),
|
||||
"ROTATE_REFRESH_TOKENS": True,
|
||||
"BLACKLIST_AFTER_ROTATION": True,
|
||||
"UPDATE_LAST_LOGIN": False,
|
||||
|
||||
"ALGORITHM": "HS256",
|
||||
"VERIFYING_KEY": "",
|
||||
"AUDIENCE": None,
|
||||
"ISSUER": None,
|
||||
"JSON_ENCODER": 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),
|
||||
|
||||
"TOKEN_OBTAIN_SERIALIZER": "rest_framework_simplejwt.serializers.TokenObtainPairSerializer",
|
||||
"TOKEN_REFRESH_SERIALIZER": "rest_framework_simplejwt.serializers.TokenRefreshSerializer",
|
||||
"TOKEN_VERIFY_SERIALIZER": "rest_framework_simplejwt.serializers.TokenVerifySerializer",
|
||||
"TOKEN_BLACKLIST_SERIALIZER": "rest_framework_simplejwt.serializers.TokenBlacklistSerializer",
|
||||
"SLIDING_TOKEN_OBTAIN_SERIALIZER": "rest_framework_simplejwt.serializers.TokenObtainSlidingSerializer",
|
||||
"SLIDING_TOKEN_REFRESH_SERIALIZER": "rest_framework_simplejwt.serializers.TokenRefreshSlidingSerializer",
|
||||
}
|
||||
|
||||
MIDDLEWARE = [
|
||||
'corsheaders.middleware.CorsMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.middleware.security.SecurityMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
@ -62,16 +117,15 @@ MIDDLEWARE = [
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
|
||||
'corsheaders.middleware.CorsMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
|
||||
]
|
||||
|
||||
ROOT_URLCONF = 'iddrs_api.urls'
|
||||
|
||||
print(BASE_DIR)
|
||||
TEMPLATES = [
|
||||
{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': [],
|
||||
'DIRS': [os.path.join(BASE_DIR,'templates')],
|
||||
'APP_DIRS': True,
|
||||
'OPTIONS': {
|
||||
'context_processors': [
|
||||
@ -97,6 +151,17 @@ DATABASES = {
|
||||
}
|
||||
}
|
||||
|
||||
## User model
|
||||
## AUTH_USER_MODEL = 'user_auth.AppUser'
|
||||
##
|
||||
## REST_FRAMEWORK = {
|
||||
## 'DEFAULT_AUTHENTICATION_CLASSES': (
|
||||
## 'rest_framework.authentication.SessionAuthentication',
|
||||
## ),
|
||||
## 'DEFAULT_PERMISSION_CLASSES': (
|
||||
## 'rest_framework.permissions.IsAuthenticated',
|
||||
## )}
|
||||
|
||||
|
||||
# Password validation
|
||||
# https://docs.djangoproject.com/en/4.1/ref/settings/#auth-password-validators
|
||||
|
@ -20,4 +20,5 @@ urlpatterns = [
|
||||
path('admin/', admin.site.urls),
|
||||
path('client_api/', include('search_tfidf.urls')),
|
||||
path('admin_api/', include('admin_api.urls')),
|
||||
path('user_auth/', include('user_auth.urls')),
|
||||
]
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -109,8 +109,8 @@ def cosine_similarity(phrase, title):
|
||||
results = dff.reset_index().to_json(orient ='records')
|
||||
results = json.loads(results)
|
||||
|
||||
with open(os.path.join(BASE_DIR, 'media/usersResults/'+phrase+'.json'), 'w', encoding='utf-8') as f:
|
||||
json.dump(results, f, ensure_ascii=True, indent=4)
|
||||
#with open(os.path.join(BASE_DIR, 'media/usersResults/'+phrase+'.json'), 'w', encoding='utf-8') as f:
|
||||
# json.dump(results, f, ensure_ascii=True, indent=4)
|
||||
|
||||
'''The results are returned from the function.'''
|
||||
return results
|
@ -11,4 +11,5 @@ router.register(r'standards', StandardsViewSet)
|
||||
urlpatterns = [
|
||||
path('', include(router.urls)),
|
||||
path('get_input/', views.get_input, name='get_input'),
|
||||
path('exportPDF/', views.exportPDF, name='exportPDF'),
|
||||
]
|
@ -6,6 +6,18 @@ from django.http import JsonResponse
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
import json
|
||||
from .tfidfSearch import cosine_similarity
|
||||
from rest_framework.decorators import api_view
|
||||
from pathlib import Path
|
||||
import os
|
||||
from django.template.loader import render_to_string
|
||||
from weasyprint import HTML
|
||||
from django.http import HttpResponse
|
||||
from django.views.generic import View
|
||||
from io import BytesIO
|
||||
from django.template.loader import get_template
|
||||
from xhtml2pdf import pisa
|
||||
|
||||
|
||||
|
||||
# Create your views here.
|
||||
|
||||
@ -37,4 +49,29 @@ def get_input(request):
|
||||
return JsonResponse({"message": "Data received", "results":searchResults})
|
||||
|
||||
|
||||
return JsonResponse({"message": "Invalid request"})
|
||||
return JsonResponse({"message": "Invalid request"})
|
||||
|
||||
@csrf_exempt
|
||||
@api_view(['POST'])
|
||||
def exportPDF(request):
|
||||
if request.method == "POST":
|
||||
filteredResults = request.data['params']['filteredResults']
|
||||
phrase = request.data['params']['phrase']
|
||||
|
||||
template = get_template('export/outputPDF.html')
|
||||
html = template.render({'results': filteredResults, 'phrase': phrase})
|
||||
#html = template.render()
|
||||
|
||||
response = HttpResponse(content_type='application/pdf')
|
||||
response['Content-Disposition'] = 'filename="output.pdf"'
|
||||
|
||||
try:
|
||||
pisa_status = pisa.CreatePDF(html, dest=response)
|
||||
if pisa_status.err:
|
||||
return HttpResponse('We had some errors <pre>' + html + '</pre>')
|
||||
|
||||
#response['Content-Type'] = 'application/pdf' # Set the Content-Type after generating the PDF
|
||||
print(response)
|
||||
return response
|
||||
except Exception as e:
|
||||
return HttpResponse(f'Error generating PDF: {str(e)}', status=500)
|
||||
|
68
templates/export/outputPDF.html
Executable file
68
templates/export/outputPDF.html
Executable file
@ -0,0 +1,68 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<!-- Required meta tags -->
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
|
||||
<!-- Bootstrap CSS -->
|
||||
|
||||
<title>{{ phrase }}</title>
|
||||
<style>
|
||||
@media print {
|
||||
body{
|
||||
width: 21cm;
|
||||
height: 29.7cm;
|
||||
margin: 15mm 15mm 15mm 15mm;
|
||||
/* change the margins as you want them to be. */
|
||||
}
|
||||
}
|
||||
p{
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
font-size: 12px !important;
|
||||
}
|
||||
.indent{
|
||||
margin-left: 15px;
|
||||
}
|
||||
.level{
|
||||
font-size: 14px !important;
|
||||
}
|
||||
.level-text-1 {
|
||||
color: #F07F4E;
|
||||
}
|
||||
|
||||
.level-text-2 {
|
||||
color: #008DCA;
|
||||
}
|
||||
|
||||
.level-text-3 {
|
||||
color: #00A554;
|
||||
}
|
||||
|
||||
.level-text-4 {
|
||||
color: #7366A3;
|
||||
}
|
||||
|
||||
.level-text-5 {
|
||||
color: #D10007;
|
||||
}
|
||||
|
||||
.level-text-6 {
|
||||
color: #CF7AB2;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>{{ phrase }}</h1>
|
||||
{% for result in results %}
|
||||
<p>
|
||||
<span class="level level-text-{{result.Level}}">Level {{ result.Level }} {{ result.LevelName }}</span>
|
||||
<br />
|
||||
IDDRS {{ result.Module }} <br /><span class="indent">{{ result.Heading1 }}
|
||||
</span>
|
||||
<br /><span class="indent">Page: {{ result.PageNum }} </span> <br />{{result.Paragraph|safe|linebreaks }}
|
||||
</p>
|
||||
<hr />
|
||||
{% endfor %}
|
||||
</body>
|
||||
</html>
|
0
user_auth/__init__.py
Normal file
0
user_auth/__init__.py
Normal file
BIN
user_auth/__pycache__/__init__.cpython-310.pyc
Normal file
BIN
user_auth/__pycache__/__init__.cpython-310.pyc
Normal file
Binary file not shown.
BIN
user_auth/__pycache__/admin.cpython-310.pyc
Normal file
BIN
user_auth/__pycache__/admin.cpython-310.pyc
Normal file
Binary file not shown.
BIN
user_auth/__pycache__/apps.cpython-310.pyc
Normal file
BIN
user_auth/__pycache__/apps.cpython-310.pyc
Normal file
Binary file not shown.
BIN
user_auth/__pycache__/models.cpython-310.pyc
Normal file
BIN
user_auth/__pycache__/models.cpython-310.pyc
Normal file
Binary file not shown.
BIN
user_auth/__pycache__/serializers.cpython-310.pyc
Normal file
BIN
user_auth/__pycache__/serializers.cpython-310.pyc
Normal file
Binary file not shown.
BIN
user_auth/__pycache__/urls.cpython-310.pyc
Normal file
BIN
user_auth/__pycache__/urls.cpython-310.pyc
Normal file
Binary file not shown.
BIN
user_auth/__pycache__/views.cpython-310.pyc
Normal file
BIN
user_auth/__pycache__/views.cpython-310.pyc
Normal file
Binary file not shown.
6
user_auth/admin.py
Normal file
6
user_auth/admin.py
Normal file
@ -0,0 +1,6 @@
|
||||
from django.contrib import admin
|
||||
from .models import *
|
||||
|
||||
# Register your models here.
|
||||
admin.site.register(AppUser)
|
||||
#admin.site.register(AppUserManager)
|
6
user_auth/apps.py
Normal file
6
user_auth/apps.py
Normal file
@ -0,0 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class UserAuthConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'user_auth'
|
31
user_auth/migrations/0001_initial.py
Normal file
31
user_auth/migrations/0001_initial.py
Normal file
@ -0,0 +1,31 @@
|
||||
# Generated by Django 4.1.3 on 2023-07-13 11:30
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('auth', '0012_alter_user_first_name_max_length'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='AppUser',
|
||||
fields=[
|
||||
('password', models.CharField(max_length=128, verbose_name='password')),
|
||||
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
|
||||
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
|
||||
('user_id', models.AutoField(primary_key=True, serialize=False)),
|
||||
('email', models.EmailField(max_length=50, unique=True)),
|
||||
('username', models.CharField(max_length=50)),
|
||||
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to.', related_name='iddrs_users', to='auth.group', verbose_name='groups')),
|
||||
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='iddrs_users', to='auth.permission', verbose_name='user permissions')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
]
|
0
user_auth/migrations/__init__.py
Normal file
0
user_auth/migrations/__init__.py
Normal file
BIN
user_auth/migrations/__pycache__/0001_initial.cpython-310.pyc
Normal file
BIN
user_auth/migrations/__pycache__/0001_initial.cpython-310.pyc
Normal file
Binary file not shown.
BIN
user_auth/migrations/__pycache__/__init__.cpython-310.pyc
Normal file
BIN
user_auth/migrations/__pycache__/__init__.cpython-310.pyc
Normal file
Binary file not shown.
51
user_auth/models.py
Normal file
51
user_auth/models.py
Normal file
@ -0,0 +1,51 @@
|
||||
from django.db import models
|
||||
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, Group, Permission
|
||||
from django.contrib.auth.base_user import BaseUserManager
|
||||
|
||||
# Create your models here.
|
||||
|
||||
class AppUserManager(BaseUserManager):
|
||||
def create_user(self, email, password=None):
|
||||
if not email:
|
||||
raise ValueError('The email must be set')
|
||||
if not password:
|
||||
raise ValueError('The password must be set')
|
||||
email = self.normalize_email(email)
|
||||
user = self.model(email=email)
|
||||
user.set_password(password)
|
||||
user.save()
|
||||
return user
|
||||
|
||||
def create_superuser(self, email, password=None):
|
||||
if not email:
|
||||
raise ValueError('The email must be set')
|
||||
if not password:
|
||||
raise ValueError('The password must be set')
|
||||
user = self.create_user(email, password)
|
||||
user.is_superuser = True
|
||||
user.save()
|
||||
return user
|
||||
|
||||
class AppUser(AbstractBaseUser, PermissionsMixin):
|
||||
user_id = models.AutoField(primary_key=True)
|
||||
email = models.EmailField(max_length=50, unique=True)
|
||||
username = models.CharField(max_length=50)
|
||||
groups = models.ManyToManyField(
|
||||
Group,
|
||||
verbose_name='groups',
|
||||
blank=True,
|
||||
help_text='The groups this user belongs to.',
|
||||
related_name='iddrs_users' # Add a unique related_name
|
||||
)
|
||||
user_permissions = models.ManyToManyField(
|
||||
Permission,
|
||||
verbose_name='user permissions',
|
||||
blank=True,
|
||||
help_text='Specific permissions for this user.',
|
||||
related_name='iddrs_users' # Add a unique related_name
|
||||
)
|
||||
USERNAME_FIELD = 'email'
|
||||
REQUIRED_FIELDS = ['username']
|
||||
objects = AppUserManager()
|
||||
def __str__(self):
|
||||
return self.username
|
32
user_auth/serializers.py
Normal file
32
user_auth/serializers.py
Normal file
@ -0,0 +1,32 @@
|
||||
from rest_framework import serializers
|
||||
from django.contrib.auth import get_user_model, authenticate
|
||||
|
||||
USERModel = get_user_model()
|
||||
|
||||
class UserRegisterSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = USERModel
|
||||
fields = '__all__'
|
||||
extra_kwargs = {'password': {'write_only': True, 'min_length': 8}}
|
||||
def create(self, clean_data):
|
||||
user_obj = USERModel.objects.create_user(email=clean_data['email'], password=clean_data['password'])
|
||||
user_obj.username = clean_data['username']
|
||||
user_obj.save()
|
||||
return user_obj
|
||||
|
||||
|
||||
class UserLoginSerializer(serializers.Serializer):
|
||||
email = serializers.EmailField()
|
||||
password = serializers.CharField()
|
||||
##
|
||||
def check_user(self, clean_data):
|
||||
user = authenticate(username=clean_data['email'], password=clean_data['password'])
|
||||
if user:
|
||||
return user
|
||||
if not user:
|
||||
raise serializers.ValidationError("Incorrect Credentials")
|
||||
|
||||
class UserSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = USERModel
|
||||
fields = ('email', 'username')
|
3
user_auth/tests.py
Normal file
3
user_auth/tests.py
Normal file
@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
9
user_auth/urls.py
Normal file
9
user_auth/urls.py
Normal file
@ -0,0 +1,9 @@
|
||||
from django.urls import path
|
||||
from . import views
|
||||
|
||||
urlpatterns = [
|
||||
path('register/', views.UserRegister.as_view(), name='register'),
|
||||
path('login/', views.UserLogin.as_view(), name='login'),
|
||||
path('logout/', views.UserLogout.as_view(), name='logout'),
|
||||
path('user/', views.UserView.as_view(), name='view'),
|
||||
]
|
48
user_auth/views.py
Normal file
48
user_auth/views.py
Normal file
@ -0,0 +1,48 @@
|
||||
from django.shortcuts import render
|
||||
from rest_framework import permissions, status
|
||||
from django.contrib.auth import get_user_model, login, logout
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework.response import Response
|
||||
from .serializers import UserRegisterSerializer, UserLoginSerializer, UserSerializer
|
||||
from rest_framework.authentication import SessionAuthentication
|
||||
|
||||
# Create your views here.
|
||||
|
||||
class UserRegister(APIView):
|
||||
permission_classes = (permissions.AllowAny,)
|
||||
serializer_class = UserRegisterSerializer
|
||||
def post(self, request):
|
||||
serializer = self.serializer_class(data=request.data)
|
||||
if serializer.is_valid():
|
||||
user = serializer.create(serializer.validated_data)
|
||||
if user:
|
||||
return Response({'message': 'User Created Successfully'}, status=status.HTTP_201_CREATED)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
class UserLogin(APIView):
|
||||
permission_classes = (permissions.AllowAny,)
|
||||
authentication_classes = (SessionAuthentication,)
|
||||
##
|
||||
serializer_class = UserLoginSerializer
|
||||
def post(self, request):
|
||||
serializer = self.serializer_class(data=request.data)
|
||||
if serializer.is_valid():
|
||||
user = serializer.check_user(serializer.validated_data)
|
||||
if user:
|
||||
login(request, user)
|
||||
return Response({'message': 'User Logged In Successfully'}, status=status.HTTP_200_OK)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
class UserLogout(APIView):
|
||||
permission_classes = (permissions.IsAuthenticated,)
|
||||
authentication_classes = (SessionAuthentication,)
|
||||
def get(self, request):
|
||||
logout(request)
|
||||
return Response({'message': 'User Logged Out Successfully'}, status=status.HTTP_200_OK)
|
||||
|
||||
class UserView(APIView):
|
||||
permission_classes = (permissions.IsAuthenticated,)
|
||||
authentication_classes = (SessionAuthentication,)
|
||||
def get(self, request):
|
||||
serializer = UserSerializer(request.user)
|
||||
return Response(serializer.data, status=status.HTTP_200_OK)
|
Loading…
Reference in New Issue
Block a user