Skip to content

Commit

Permalink
Merge pull request #29 from SheCodesAus/DEV
Browse files Browse the repository at this point in the history
merge main
  • Loading branch information
shayzimm authored Apr 2, 2024
2 parents 1dd18ad + 7547488 commit 0363d78
Show file tree
Hide file tree
Showing 9 changed files with 230 additions and 23 deletions.
5 changes: 3 additions & 2 deletions DiversiTech/DiversiTech/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,9 @@

REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
]
'rest_framework.authentication.TokenAuthentication'
],
'DATE_INPUT_FORMATS':["%d-%m-%Y", "%m/%Y"]
}

AUTH_USER_MODEL = 'users.CustomUser'
Expand Down
29 changes: 29 additions & 0 deletions DiversiTech/profiles/migrations/0007_experience.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Generated by Django 5.0.3 on 2024-03-31 07:58

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('profiles', '0006_profile_tags_alter_profile_industries'),
]

operations = [
migrations.CreateModel(
name='Experience',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('experience_type', models.CharField(choices=[('Volunteering', 'Volunteering'), ('Project', 'Project'), ('Talk', 'Talk'), ('Mentoring', 'Mentoring'), ('Job', 'Job')], default='Job', max_length=50)),
('description', models.CharField(max_length=1000)),
('url', models.URLField(blank=True, null=True)),
('picture_url', models.URLField(blank=True, null=True)),
('is_present_experience', models.BooleanField(default=False)),
('start_date', models.DateField()),
('end_date', models.DateField(blank=True, null=True)),
],
options={
'verbose_name_plural': 'Experiences',
},
),
]
20 changes: 20 additions & 0 deletions DiversiTech/profiles/migrations/0008_experience_profile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Generated by Django 5.0.3 on 2024-03-31 08:10

import django.db.models.deletion
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('profiles', '0007_experience'),
]

operations = [
migrations.AddField(
model_name='experience',
name='profile',
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, related_name='profile_experiences', to='profiles.profile'),
preserve_default=False,
),
]
37 changes: 36 additions & 1 deletion DiversiTech/profiles/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from django.db import models
from django.contrib.auth import get_user_model
from django.core.exceptions import ValidationError
# from django.contrib.postgres.fields import DateRangeField


class Tag(models.Model):
Expand Down Expand Up @@ -63,4 +64,38 @@ def __str__(self):
industries = models.ManyToManyField(Industry, related_name='industry_profiles', blank=True)
tags = models.ManyToManyField(Tag, related_name='tagged_profiles', blank=True)


class Experience(models.Model):

experience_type_choices = (
("Volunteering", "Volunteering"),
("Project", "Project"),
("Talk", "Talk"),
("Mentoring", "Mentoring"),
("Job", "Job")
)
profile = models.ForeignKey(
'Profile',
on_delete=models.CASCADE,
related_name='profile_experiences')

experience_type = models.CharField(max_length=50, choices=experience_type_choices, default="Job")
description = models.CharField(max_length=1000, null=False, blank=False)
url = models.URLField(null=True, blank=True)
picture_url = models.URLField(null=True, blank=True)
is_present_experience = models.BooleanField(null=False, blank=False, default=False)
start_date = models.DateField(blank=False, null=False)
end_date = models.DateField(blank=True, null=True)

def start_date_formatted(self):
return self.start_date.strftime("%b %Y")

def end_date_formatted(self):
if self.end_date:
return self.end_date.strftime("%b %Y")
return "Present"

def __str__(self):
return f"{self.description} - {self.start_date_formatted()} to {self.end_date_formatted()}"

class Meta:
verbose_name_plural = 'Experiences'
15 changes: 14 additions & 1 deletion DiversiTech/profiles/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,17 @@ def has_object_permission(self, request, view, obj):
if request.user.is_staff:
return True

return obj.owner==request.user
return obj.owner==request.user

class IsProfileOwnerOrAdminOrReadOnly(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
profile_id = obj.profile.owner.id

if request.method in permissions.SAFE_METHODS:
return True

if request.user.is_staff:
return True
print(profile_id)
print(request.user.id)
return profile_id==request.user.id
31 changes: 28 additions & 3 deletions DiversiTech/profiles/serializers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from rest_framework import serializers
from .models import Profile, Industry, Tag
import datetime
from .models import Profile, Industry, Tag, Experience
from .validators import validate_industries, validate_unique_tag, validate_unique_industry

class TagSerializer(serializers.ModelSerializer):
Expand Down Expand Up @@ -40,9 +41,20 @@ class Meta:
fields = '__all__'


class ProfileDetailSerializer (ProfileSerializer):

class ExperienceSerializer(serializers.ModelSerializer):
profile = serializers.ReadOnlyField(source='profile.id')

class Meta:
model = Experience
fields = '__all__'




class ProfileDetailSerializer (ProfileSerializer):
profile_experiences = ExperienceSerializer(many=True, read_only=True)

def update(self, instance, validated_data):

# clear existing industries
Expand Down Expand Up @@ -73,4 +85,17 @@ def update(self, instance, validated_data):
instance.is_seeking_mentorship = validated_data.get('is_seeking_mentorship', instance.is_seeking_mentorship)

instance.save()
return instance
return instance

class ExperienceDetailSerializer(ExperienceSerializer):

def update(self, instance, validated_data):
instance.experience_type = validated_data.get('experience_type', instance.experience_type)
instance.description = validated_data.get('description', instance.description)
instance.url = validated_data.get('url', instance.url)
instance.picture_url = validated_data.get('picture_url',instance.picture_url)
instance.is_present_experience = validated_data.get('is_present_experience', instance.is_present_experience)
instance.start_date = validated_data.get('start_date', instance.start_date)
instance.end_date = validated_data.get('end_date', instance.end_date)
instance.save()
return instance
5 changes: 4 additions & 1 deletion DiversiTech/profiles/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,8 @@
path('industries/', views.IndustryList.as_view()),
path('industries/<int:pk>/', views.IndustryList.as_view()),
path('tags/', views.TagList.as_view()),
path('tag/<int:pk>/', views.TagList.as_view())
path('tag/<int:pk>/', views.TagList.as_view()),
path('experiences/', views.ExperienceList.as_view()),
path('profile/<int:profile_id>/experiences/', views.ExperienceList.as_view()),
path('experience/<int:pk>', views.ExperienceDetail.as_view()),
]
99 changes: 95 additions & 4 deletions DiversiTech/profiles/views.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import Profile, Industry, Tag
from .serializers import ProfileSerializer, ProfileDetailSerializer, IndustrySerializer, TagSerializer
from .models import Profile, Industry, Tag, Experience
from .serializers import (ProfileSerializer, ProfileDetailSerializer,
IndustrySerializer, TagSerializer, ExperienceSerializer, ExperienceDetailSerializer)
from django.http import Http404
from rest_framework import status, permissions
from .permissions import IsOwnerOrAdminOrReadOnly
from .permissions import IsOwnerOrAdminOrReadOnly, IsProfileOwnerOrAdminOrReadOnly


class TagList(APIView):
Expand Down Expand Up @@ -167,4 +168,94 @@ def delete(self,request, pk):
profile = self.get_object(pk)
profile.delete()
return Response({"detail":"Profile deleted successfully"}, status=status.HTTP_200_OK)




class ExperienceList(APIView):
permission_classes = [permissions.IsAuthenticatedOrReadOnly]

def get(self, request, profile_id=None):
if profile_id:
experiences = Experience.objects.all().filter(profile=profile_id)
else:
experiences = Experience.objects.all()
serializer = ExperienceSerializer(experiences, many=True)
return Response(serializer.data)



def post(self, request, profile_id):
serializer = ExperienceSerializer(data=request.data)

try:
profile = Profile.objects.get(id=profile_id)
self.check_object_permissions(self.request, profile)

if serializer.is_valid():
serializer.save(profile=profile) # Use 'profile' instead of 'profile_instance'
return Response(serializer.data, status=status.HTTP_201_CREATED)

return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

except Profile.DoesNotExist:
raise Http404

# profile_instance = Profile.objects.get(id=profile_id)

# if not profile_instance:
# return Response(
# {"detail": "Profile doesn't exist."}, status=status.HTTP_403_FORBIDDEN)
# if serializer.is_valid():


# serializer.save(profile=profile_instance)
# return Response(
# serializer.data, status=status.HTTP_201_CREATED
# )
# return Response(
# serializer.errors,
# status=status.HTTP_400_BAD_REQUEST
# )

class ExperienceDetail(APIView):

permission_classes = [
IsProfileOwnerOrAdminOrReadOnly
]

# getting the object from the database
def get_object(self, pk):
try:
experience=Experience.objects.get(pk=pk)
self.check_object_permissions(self.request, experience)
return experience
except Experience.DoesNotExist:
raise Http404

# passing the object to the serializer and returning serialized data
def get(self, request, pk):
experience = self.get_object(pk)
serializer = ExperienceDetailSerializer(experience)
return Response(serializer.data, status=status.HTTP_200_OK)

def put (self, request, pk):
experience = self.get_object(pk)
serializer = ExperienceDetailSerializer(
instance=experience,
data=request.data,
partial=True
)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_200_OK)

return Response(
serializer.errors,
status=status.HTTP_400_BAD_REQUEST
)


def delete(self,request, pk):
experience = self.get_object(pk)
experience.delete()
return Response({"detail": "Experience deleted successfully"}, status=status.HTTP_204_NO_CONTENT)
12 changes: 1 addition & 11 deletions DiversiTech/users/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,13 @@ def post(self, request, *args, **kwargs):
return Response ({
'token': token.key,
'user_id': user.pk,
'is_staff': user.is_staff,
})


class CustomUserList(APIView):

def get(self, request):
# if not request.user.is_staff:
# return Response(
# {"message": "You do not have permission to view these records"},
# status=status.HTTP_403_FORBIDDEN
# )
users = CustomUser.objects.all()
serializer = CustomUserSerializer(users, many=True)
return Response(serializer.data)
Expand Down Expand Up @@ -85,12 +81,6 @@ def get_object(self, pk):
def get(self, request, pk):
user = self.get_object(pk)

if user != request.user and not request.user.is_staff:
return Response(
{"detail": "You are not authorized to view this record"},
status=status.HTTP_403_FORBIDDEN
)

serializer = CustomUserSerializer(user)
return Response(serializer.data)

Expand Down

0 comments on commit 0363d78

Please sign in to comment.