when i try to add a post to my server i get 401 Unauthorized i sent my jwt in postman with Bearer jwt but nothing change . i think the probleme in the api where exactly i don't have any idea
i use django as backend and react as frontend those are all my code
urls.py :
from django.contrib import admin
from django.urls import path, include, re_path
from django.views.generic import TemplateView
urlpatterns = [
#path('admin/', admin.site.urls),
path('auth/', include('djoser.urls')),
path('auth/', include('djoser.urls.jwt')),
path('', include('crm.urls')),
]
urlpatterns += [re_path(r'^.*', TemplateView.as_view(template_name='index.html'))]
views.py :
from django.shortcuts import render ,redirect ,get_object_or_404
from rest_framework.parsers import MultiPartParser, FormParser
from .serializers import PostSerializer
from rest_framework.viewsets import ModelViewSet, GenericViewSet
from .forms import CreateUserForm, LoginForm
from rest_framework.response import Response
from rest_framework import status
#, UploadForm
from rest_framework.decorators import api_view, action
from django.contrib.auth.decorators import login_required, user_passes_test
from .models import Post, PostImage
# - Authentication models and functions
from django.contrib.auth.models import auth
from django.contrib.auth import authenticate, login, logout
def homepage(request):
return render(request, 'crm/index.html')
def register(request):
form = CreateUserForm()
if request.method == "POST":
form = CreateUserForm(request.POST)
if form.is_valid():
form.save()
return redirect("my-login")
context = {'registerform':form}
return render(request, 'crm/register.html', context=context)
def my_login(request):
form = LoginForm()
if request.method == 'POST':
form = LoginForm(request, data=request.POST)
if form.is_valid():
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(request, username=username,password=password)
if user is not None :
auth.login(request, user)
return redirect("dashboard")
context = {'loginform':form}
return render(request, 'crm/my-login.html', context=context)
def user_logout(request):
auth.logout(request)
return redirect("")
#def upload(request):
# if request.POST:
# form = UploadForm(request.POST, request.FILES)
# print(request.FILES)
# if form.is_valid():
# form.save_()
# return redirect(homepage)
#return render(request, 'crm/upload.html', {'form' : UploadForm })
def post_view(request):
posts = Post.objects.all()
return render(request, 'post.html', {'posts':posts})
def detail_view(request, id):
post = get_object_or_404(Post, id=id)
photos = PostImage.objects.filter(post=post)
return render(request, 'detail.html', {
'post':post,
'photos':photos
})
@api_view(['POST'])
class PostsViewSet(ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
parser_classes = (MultiPartParser, FormParser)
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
@login_required(login_url="my-login")
def dashboard(request):
return render(request, 'crm/dashboard.html')
serializers.py :
from djoser.serializers import UserCreateSerializer
from django.contrib.auth import get_user_model
from rest_framework import serializers
from .models import Post, PostImage
User = get_user_model()
class CustomUserCreateSerializer(UserCreateSerializer):
age = serializers.IntegerField(required=True)
role = serializers.ChoiceField(choices=User.Role.choices, required=True)
class Meta(UserCreateSerializer.Meta):
model = User
fields = ('id', 'email', 'name', 'password', 'age', 'role')
def create(self, validated_data):
user = User.objects.create_user(**validated_data)
return user
class PostImageSerializer(serializers.ModelSerializer):
class Meta:
model = PostImage
fields = ('id', 'post', 'image')
class PostSerializer(serializers.ModelSerializer):
images = PostImageSerializer(many=True, read_only=True)
uploaded_images = serializers.ListField(
child = serializers.ImageField(max_length = 1000000, allow_empty_file = False, use_url = False),
write_only=True)
class Meta:
model = Post
fields = ('id', 'title', 'text', 'category', 'author', 'created_at', 'images', "uploaded_images")
def create(self, validated_data):
uploaded_images = validated_data.pop("uploaded_images")
post = Post.objects.create(**validated_data)
for image in uploaded_images:
newpost_image = PostImage.objects.create(post=post, image=image)
return post
models.py :
from django.db import models
from django.contrib.auth.models import PermissionsMixin , AbstractBaseUser, BaseUserManager
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.core.validators import MinValueValidator, MaxValueValidator
from django.utils.translation import gettext_lazy as _
from django.core.exceptions import ValidationError
class CustomUserManager(BaseUserManager):
def create_user(self, email, name, password=None, **extra_fields):
if not email:
raise ValueError(_('The Email field must be set'))
email = self.normalize_email(email)
user = self.model(email=email, name=name, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, name, password=None, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
if extra_fields.get('is_staff') is not True:
raise ValueError(_('Superuser must have is_staff=True.'))
if extra_fields.get('is_superuser') is not True:
raise ValueError(_('Superuser must have is_superuser=True.'))
return self.create_user(email, name, password, **extra_fields)
class User(AbstractBaseUser):
email = models.EmailField(_('email address'), unique=True)
name = models.CharField(_('name'), max_length=150, default='Anonymous', unique=False)
age = models.PositiveIntegerField(_('age'), blank=True, null=True, validators=[MinValueValidator(18), MaxValueValidator(100)])
is_active = models.BooleanField(_('active'), default=True)
is_staff = models.BooleanField(_('staff status'), default=False)
class Role(models.TextChoices):
ADMIN = "ADMIN", "Admin"
CLIENT = "CLIENT", "Client"
ANALYST = "ANALYST", "Analyst"
role = models.CharField(_('role'), max_length=50, choices=Role.choices, default=Role.CLIENT)
objects = CustomUserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['name', 'age', 'role']
def save(self, *args, **kwargs):
if not self.pk:
if not self.email:
raise ValidationError("Email address is required.")
elif User.objects.filter(email=self.email).exists():
raise ValidationError("Email address must be unique.")
elif not self.role:
self.role = self.Role.CLIENT
super().save(*args, **kwargs)
class ClientManager(CustomUserManager):
def get_queryset(self, *args, **kwargs):
return super().get_queryset(*args, **kwargs).filter(role=User.Role.CLIENT)
class Client(User):
base_role = User.Role.CLIENT
objects = ClientManager()
class Meta:
proxy = True
def welcome(self):
return "Only for Client"
class AnalystManager(CustomUserManager):
def get_queryset(self, *args, **kwargs):
return super().get_queryset(*args, **kwargs).filter(role=User.Role.ANALYST)
class Analyst(User):
base_role = User.Role.ANALYST
objects = AnalystManager()
class Meta:
proxy = True
def welcome(self):
return "Only for Analysts"
class Post(models.Model):
CATEGORY_CHOICES = [
('math', 'Math'),
('philosophy', 'Philosophy'),
('science', 'Science'),
('political', 'Political'),
('other', 'Other'),
]
title = models.CharField(max_length=250, blank=False) # Required field
text = models.TextField(blank=False) # Required field
category = models.CharField(max_length=25, choices=CATEGORY_CHOICES, blank=False) # Required field
author = models.CharField(max_length=100) # You can adjust the max length as needed
created_at = models.DateTimeField(auto_now_add=True) # Automatically set to the current date and time when created
def __str__(self):
return self.title
class PostImage(models.Model):
post = models.ForeignKey(Post, default=None ,on_delete=models.CASCADE, related_name = "images")
image = models.ImageField(upload_to='djangoposts/files/images', default="", null=True, blank=True)
def __str__(self):
return self.post.title
i try to put a jwt token in the Bearer Token in postman but nothing have change the same error still show up