fix call to removed viewset, fix filter on comment

This commit is contained in:
yann 2025-06-06 11:55:41 +02:00
parent 5eb0be8003
commit 79e577acd2
5 changed files with 26 additions and 67 deletions

View File

@ -67,3 +67,4 @@ YaL <yann@needsome.coffee>
MIT License MIT License
Copyright (c) 2025 Copyright (c) 2025

View File

@ -129,7 +129,9 @@ DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
AUTH_USER_MODEL = 'authentication.User' AUTH_USER_MODEL = 'authentication.User'
REST_FRAMEWORK = { REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': ('rest_framework_simplejwt.authentication.JWTAuthentication',) 'DEFAULT_AUTHENTICATION_CLASSES': ('rest_framework_simplejwt.authentication.JWTAuthentication',),
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
'PAGE_SIZE': 5
} }
SIMPLE_JWT = { SIMPLE_JWT = {

View File

@ -17,17 +17,15 @@ Including another URLconf
from django.contrib import admin from django.contrib import admin
from django.urls import path, include from django.urls import path, include
from authentication.views import (UserView, UserCreateView, PasswordUpdateView) from authentication.views import (UserView, UserCreateView, PasswordUpdateView)
from support.views import ProjectViewSet, IssueViewSet, CommentViewSet, ContributorViewSet from support.views import ProjectViewSet, IssueViewSet, CommentViewSet
from rest_framework import routers from rest_framework import routers
from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView
router = routers.SimpleRouter() router = routers.SimpleRouter()
#router.register('user', UserViewSet, basename='user')
router.register('project', ProjectViewSet, basename='project') router.register('project', ProjectViewSet, basename='project')
router.register('issue', IssueViewSet, basename='issue') router.register('issue', IssueViewSet, basename='issue')
router.register('comment', CommentViewSet, basename='comment') router.register('comment', CommentViewSet, basename='comment')
router.register('contributors', ContributorViewSet)
urlpatterns = [ urlpatterns = [
path('admin/', admin.site.urls), path('admin/', admin.site.urls),

View File

@ -22,8 +22,6 @@ class ContributorListSerializer(ModelSerializer):
fields = ['contributor'] fields = ['contributor']
class ProjectSerializer(ModelSerializer): class ProjectSerializer(ModelSerializer):
author = StringRelatedField(many=False) author = StringRelatedField(many=False)
@ -60,29 +58,14 @@ class ProjectDetailSerializer(ModelSerializer):
class IssueSerializer(ModelSerializer): class IssueSerializer(ModelSerializer):
author = StringRelatedField(many=False) author = StringRelatedField(many=False)
class Meta: class Meta:
model = Issue model = Issue
fields = ['id', 'title', 'project', 'date_created', 'priority', fields = ['id', 'title', 'project', 'date_created', 'priority',
'tag', 'status', 'author'] 'tag', 'status', 'author']
def validate_project(self, data):
# if data['user'] not in data['project'].contributors:
# raise ValidationError("User must be a contributor to the project")
#print(data.project)
#if self.context['request'].user not in data.contributors:
# raise ValidationError("User must be a contributor to the project")
#print(self.get_contributors(data))
return data
class IssueDetailSerializer(ModelSerializer): class IssueDetailSerializer(ModelSerializer):
comments = SerializerMethodField() comments = SerializerMethodField()

View File

@ -1,8 +1,4 @@
from django.contrib.auth.checks import check_models_permissions
from django.shortcuts import render
from rest_framework.serializers import raise_errors_on_nested_writes
from rest_framework.viewsets import ModelViewSet from rest_framework.viewsets import ModelViewSet
from rest_framework.views import APIView
from support.models import Project, ProjectContributor, Issue, Comment from support.models import Project, ProjectContributor, Issue, Comment
from authentication.models import User from authentication.models import User
from support.serializers import (ProjectSerializer, from support.serializers import (ProjectSerializer,
@ -20,16 +16,13 @@ from rest_framework.permissions import (IsAuthenticated,
IsAuthenticatedOrReadOnly) IsAuthenticatedOrReadOnly)
from support.permissions import IsAuthor, IsContributor from support.permissions import IsAuthor, IsContributor
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.exceptions import ValidationError
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
class ProjectViewSet(ModelViewSet): class ProjectViewSet(ModelViewSet):
permission_classes = [IsAuthenticatedOrReadOnly] permission_classes = [IsAuthenticatedOrReadOnly]
serializer_class = ProjectSerializer serializer_class = ProjectSerializer
detail_serializer_class = ProjectDetailSerializer detail_serializer_class = ProjectDetailSerializer
queryset = Project.objects.filter(active=True) queryset = Project.objects.filter(active=True)
@ -56,7 +49,6 @@ class ProjectViewSet(ModelViewSet):
serialized.save() serialized.save()
return Response(serialized.data) return Response(serialized.data)
def perform_create(self, serializer): def perform_create(self, serializer):
"""set authenticated user as author and contributor on creation""" """set authenticated user as author and contributor on creation"""
test = serializer.save(author=self.request.user) test = serializer.save(author=self.request.user)
@ -65,15 +57,6 @@ class ProjectViewSet(ModelViewSet):
if contributor_serializer.is_valid(): if contributor_serializer.is_valid():
contributor_serializer.save() contributor_serializer.save()
@action(detail=True, methods=['patch'], permission_classes=[IsContributor])
def test(self, request, pk):
"""only for testing purpose, should be deleted not published"""
if not request.user in Project.objects.get(id=pk).contributors.all():
raise PermissionDenied()
print(request.data)
return Response("OK")
@action(detail=True, methods=['patch'], permission_classes=[IsContributor]) @action(detail=True, methods=['patch'], permission_classes=[IsContributor])
def contributor(self, request, pk): def contributor(self, request, pk):
"""Add a contributor to a project """Add a contributor to a project
@ -82,7 +65,6 @@ class ProjectViewSet(ModelViewSet):
#check if requestor is contributor #check if requestor is contributor
if not request.user in Project.objects.get(id=pk).contributors.all(): if not request.user in Project.objects.get(id=pk).contributors.all():
raise PermissionDenied() raise PermissionDenied()
if request.data is None or not 'contributor' in request.data: if request.data is None or not 'contributor' in request.data:
return Response(f"Key error;`contributor` is expected", return Response(f"Key error;`contributor` is expected",
status=status.HTTP_400_BAD_REQUEST) status=status.HTTP_400_BAD_REQUEST)
@ -100,10 +82,8 @@ class ProjectViewSet(ModelViewSet):
status=status.HTTP_226_IM_USED) status=status.HTTP_226_IM_USED)
class IssueViewSet(ModelViewSet): class IssueViewSet(ModelViewSet):
permission_classes = [IsAuthenticatedOrReadOnly] permission_classes = [IsAuthenticated]
serializer_class = IssueSerializer serializer_class = IssueSerializer
detail_serializer_class = IssueDetailSerializer detail_serializer_class = IssueDetailSerializer
@ -112,7 +92,6 @@ class IssueViewSet(ModelViewSet):
return self.detail_serializer_class return self.detail_serializer_class
return super().get_serializer_class() return super().get_serializer_class()
def get_queryset(self): def get_queryset(self):
""" """
returns only the issues related to projects returns only the issues related to projects
@ -128,24 +107,26 @@ class IssueViewSet(ModelViewSet):
#query on a list #query on a list
return Issue.objects.filter(project__in=projects) return Issue.objects.filter(project__in=projects)
def perform_update(self, serializer): def perform_update(self, serializer):
"""
Check if requestor is author allows him to partial update
change the author to assign issue
"""
issue = self.get_object() issue = self.get_object()
if not self.request.user == issue.author: if not self.request.user == issue.author:
raise PermissionDenied() raise PermissionDenied()
if serializer.is_valid(raise_exception=True): if serializer.is_valid(raise_exception=True):
if self.request.data['author']:
requested_author = User.objects.get( requested_author = User.objects.get(
username=self.request.data['author']) username=self.request.data['author'])
serializer.save(author=requested_author) serializer.save(author=requested_author)
return Response(serializer.data) return Response(serializer.data)
return Response("Data error", status=status.HTTP_400_BAD_REQUEST) return Response("Data error", status=status.HTTP_400_BAD_REQUEST)
@action(detail=True, methods=['get']) @action(detail=True, methods=['get'])
def contributors(self, request, pk): def contributors(self, request, pk):
""" """
check if requestor is contributor then returns the list Check if requestor is contributor then returns the list
of the contributors to the issue's project or raise unauthorized of the contributors to the issue's project or raise unauthorized
""" """
issue = Issue.objects.get(id=pk) issue = Issue.objects.get(id=pk)
@ -154,7 +135,6 @@ class IssueViewSet(ModelViewSet):
else: else:
raise PermissionDenied() raise PermissionDenied()
def create(self, request, *args, **kwargs): def create(self, request, *args, **kwargs):
if not 'project' in request.data: if not 'project' in request.data:
return Response("A project id is required", return Response("A project id is required",
@ -173,39 +153,34 @@ class IssueViewSet(ModelViewSet):
return Response(response, status = status.HTTP_201_CREATED) return Response(response, status = status.HTTP_201_CREATED)
class CommentViewSet(ModelViewSet): class CommentViewSet(ModelViewSet):
permission_classes = [IsAuthenticatedOrReadOnly] permission_classes = [IsAuthenticated]
serializer_class = CommentListSerializer serializer_class = CommentListSerializer
detail_serializer_class = CommentDetailSerializer detail_serializer_class = CommentDetailSerializer
queryset = Comment.objects.all() queryset = Comment.objects.all()
def get_queryset(self): def get_queryset(self):
"""returns only comments associated with issue where the requestor """
Returns only comments associated with issue where the requestor
is project's contributor is project's contributor
""" """
if self.request.GET.get('issue'): if self.request.GET.get('issue'):
issue_id = int(self.request.GET.get('issue')) issue_id = int(self.request.GET.get('issue'))
print(issue_id, type(issue_id))
project = Issue.objects.get(id=issue_id).project project = Issue.objects.get(id=issue_id).project
if not self.request.user in Issue.objects.get( if not self.request.user in project.contributors.all():
id=issue_id).project.contributors.all():
raise PermissionDenied() raise PermissionDenied()
return Comment.objects.filter(issue=issue_id) return Comment.objects.filter(issue=issue_id)
if self.request.data: #or returns those from projects where requestor is contributing
return Comment.objects.filter(issue=self.request.data['issue']) projects = Project.objects.filter(contributors=self.request.user).values('id')
print(projects)
issues = Issue.objects.filter(project__in=projects)
return Comment.objects.filter(issue__in=issues)
def get_serializer_class(self): def get_serializer_class(self):
if self.action == 'retrieve': if self.action == 'retrieve':
return self.detail_serializer_class return self.detail_serializer_class
return super().get_serializer_class() return super().get_serializer_class()
def create(self, request, *args, **kwargs): def create(self, request, *args, **kwargs):
user = request.user user = request.user
issue = Issue.objects.get(id=request.data['issue']) issue = Issue.objects.get(id=request.data['issue'])