update des modèles en BDD et de l'authentification
This commit is contained in:
parent
dd6a70c37f
commit
2c79f1aca9
2
.gitignore
vendored
2
.gitignore
vendored
@ -2,4 +2,4 @@
|
||||
.project
|
||||
.pydevproject
|
||||
poetry.lock
|
||||
|
||||
.env
|
||||
|
||||
@ -11,16 +11,18 @@ https://docs.djangoproject.com/en/5.2/ref/settings/
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
import os
|
||||
from dotenv import load_dotenv, dotenv_values
|
||||
|
||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||
load_dotenv()
|
||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||
|
||||
|
||||
# Quick-start development settings - unsuitable for production
|
||||
# See https://docs.djangoproject.com/en/5.2/howto/deployment/checklist/
|
||||
|
||||
# SECURITY WARNING: keep the secret key used in production secret!
|
||||
SECRET_KEY = 'django-insecure-g)a6wc^%c58nxv6x2&&o1tnh=dcpy)jd01nuc(x-6+23&0ay3y'
|
||||
SECRET_KEY = os.getenv("DJANGO_SECRET_KEY")
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = True
|
||||
@ -37,7 +39,6 @@ CORS_ALLOWED_ORIGINS = [
|
||||
|
||||
|
||||
# Application definition
|
||||
|
||||
INSTALLED_APPS = [
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
@ -49,9 +50,10 @@ INSTALLED_APPS = [
|
||||
'rest_framework',
|
||||
'corsheaders',
|
||||
'rest_framework_simplejwt',
|
||||
'djoser',
|
||||
]
|
||||
|
||||
AUTH_USER_MODEL = 'books.CustomUser'
|
||||
|
||||
MIDDLEWARE = [
|
||||
'django.middleware.security.SecurityMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
@ -98,11 +100,11 @@ WSGI_APPLICATION = 'api.wsgi.application'
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.postgresql',
|
||||
'NAME': 'pipi',
|
||||
'USER': 'pipi',
|
||||
'PASSWORD': 'pipi',
|
||||
'HOST': 'localhost',
|
||||
'PORT': '5434'
|
||||
'NAME': os.getenv("DB_NAME"),
|
||||
'USER': os.getenv("DB_USER"),
|
||||
'PASSWORD': os.getenv("DB_PASSWORD"),
|
||||
'HOST': os.getenv("DB_HOST"),
|
||||
'PORT': os.getenv("DB_PORT")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
14
api/urls.py
14
api/urls.py
@ -15,11 +15,17 @@ Including another URLconf
|
||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||
"""
|
||||
from django.contrib import admin
|
||||
from django.urls import path, include, re_path
|
||||
from django.urls import path
|
||||
from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView
|
||||
|
||||
from books import views
|
||||
from books.views import UserProfileView, BookListCreateView
|
||||
|
||||
urlpatterns = [
|
||||
re_path(r'^auth/', include('djoser.urls')),
|
||||
re_path(r'^auth/', include('djoser.urls.jwt')),
|
||||
path('', include('books.urls')),
|
||||
path('admin/', admin.site.urls),
|
||||
path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
|
||||
path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
|
||||
path('api/profile', UserProfileView.as_view(), name='user_profile'),
|
||||
path('api/books', BookListCreateView.as_view(), name='book_list_create'),
|
||||
path('api/users/<int:user_id>', views.find_user_by_id, name='user-detail')
|
||||
]
|
||||
@ -1,4 +1,6 @@
|
||||
from django.contrib import admin
|
||||
from books.models import Book
|
||||
from books.models import Book, CustomUser
|
||||
|
||||
# Register your models here.
|
||||
admin.site.register(Book)
|
||||
admin.site.register(CustomUser)
|
||||
@ -1,25 +0,0 @@
|
||||
# Generated by Django 5.2.7 on 2025-11-02 22:07
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Book',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('title', models.CharField(max_length=255)),
|
||||
('author', models.CharField(max_length=255)),
|
||||
('state', models.CharField(choices=[('PLAN', 'Plan to Read'), ('READING', 'Reading'), ('COMPLETED', 'Completed'), ('DROPPED', 'Dropped')], db_index=True, default='PLAN', max_length=10, verbose_name='state')),
|
||||
('added_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
],
|
||||
),
|
||||
]
|
||||
@ -1,19 +0,0 @@
|
||||
# Generated by Django 5.2.7 on 2025-11-04 17:16
|
||||
|
||||
import django.core.validators
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('books', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='book',
|
||||
name='note',
|
||||
field=models.PositiveSmallIntegerField(blank=True, null=True, validators=[django.core.validators.MaxValueValidator(10)], verbose_name='note'),
|
||||
),
|
||||
]
|
||||
@ -1,19 +0,0 @@
|
||||
# Generated by Django 5.2.7 on 2025-11-04 17:18
|
||||
|
||||
import django.core.validators
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('books', '0002_book_note'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='book',
|
||||
name='note',
|
||||
field=models.PositiveSmallIntegerField(blank=True, default=0, null=True, validators=[django.core.validators.MaxValueValidator(10)], verbose_name='note'),
|
||||
),
|
||||
]
|
||||
@ -1,28 +1,35 @@
|
||||
from django.contrib.auth.models import AbstractUser
|
||||
from django.db import models
|
||||
from django.conf import settings
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.core.validators import MaxValueValidator
|
||||
|
||||
# Create your models here.
|
||||
class Book(models.Model):
|
||||
PLAN_TO_READ = 'PLAN'
|
||||
READING = 'READING'
|
||||
COMPLETED = 'COMPLETED'
|
||||
DROPPED = 'DROPPED'
|
||||
|
||||
STATE_CHOICES = [
|
||||
(PLAN_TO_READ, _('Plan to Read')),
|
||||
(READING, _('Reading')),
|
||||
(COMPLETED, _('Completed')),
|
||||
(DROPPED, _('Dropped')),
|
||||
]
|
||||
|
||||
user = models.ForeignKey(
|
||||
settings.AUTH_USER_MODEL,
|
||||
on_delete=models.CASCADE,
|
||||
related_name='books'
|
||||
)
|
||||
|
||||
note = models.PositiveSmallIntegerField(
|
||||
_('note'),
|
||||
validators=[
|
||||
MaxValueValidator(10)
|
||||
],
|
||||
default=0,
|
||||
null=True,
|
||||
blank=True
|
||||
)
|
||||
_('note'),
|
||||
validators=[MaxValueValidator(10)],
|
||||
default=0,
|
||||
null=True,
|
||||
blank=True
|
||||
)
|
||||
title = models.CharField(max_length=255)
|
||||
author = models.CharField(max_length=255)
|
||||
state = models.CharField(
|
||||
@ -35,4 +42,10 @@ class Book(models.Model):
|
||||
added_at = models.DateTimeField(auto_now_add=True)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.title} ({self.user.username})"
|
||||
|
||||
|
||||
class CustomUser(AbstractUser):
|
||||
def __str__(self):
|
||||
return self.username
|
||||
@ -1,9 +1,10 @@
|
||||
from rest_framework.decorators import api_view
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.permissions import IsAuthenticatedOrReadOnly
|
||||
from rest_framework.permissions import IsAuthenticatedOrReadOnly, IsAuthenticated
|
||||
from rest_framework import status
|
||||
|
||||
from .models import Book
|
||||
from .models import Book, CustomUser
|
||||
from .serializers import BookSerializer
|
||||
|
||||
class BookListCreateView(APIView):
|
||||
@ -21,3 +22,32 @@ class BookListCreateView(APIView):
|
||||
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
||||
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
|
||||
@api_view(['GET'])
|
||||
def find_user_by_id(request, user_id):
|
||||
try:
|
||||
user = CustomUser.objects.get(id=user_id)
|
||||
books_queryset = Book.objects.filter(user=user)
|
||||
books_serializer = BookSerializer(books_queryset, many=True)
|
||||
|
||||
return Response({
|
||||
'username': user.username,
|
||||
'email': user.email,
|
||||
'books': books_serializer.data,
|
||||
})
|
||||
except CustomUser.DoesNotExist:
|
||||
return Response({"message": "Cet utilisateur n'existe pas"}, status=404)
|
||||
|
||||
class UserProfileView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get(self,request):
|
||||
user = request.user
|
||||
books_queryset = Book.objects.filter(user=user)
|
||||
books_serializer = BookSerializer(books_queryset, many=True)
|
||||
return Response({
|
||||
'username': user.username,
|
||||
'email': user.email,
|
||||
'books': books_serializer.data,
|
||||
})
|
||||
@ -8,7 +8,7 @@ services:
|
||||
POSTGRES_PASSWORD: pipi
|
||||
POSTGRES_DB: pipi
|
||||
ports:
|
||||
- "5434:5432"
|
||||
- "5433:5432"
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
|
||||
|
||||
@ -9,9 +9,9 @@ license = "MIT"
|
||||
[tool.poetry.dependencies]
|
||||
python = ">=3.13,<4.0"
|
||||
Django = "^5.2.7"
|
||||
djoser = "^2.3.3"
|
||||
djangorestframework = ">=3.16.1"
|
||||
djangorestframework_simplejwt = "^5.5.1"
|
||||
django-cors-headers = "^4.9.0"
|
||||
psycopg = "^3.1"
|
||||
gunicorn = "^22.0"
|
||||
dotenv = "^0.9.9"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user