Commit 4261cddf authored by Fahmi's avatar Fahmi

commit ke 3

parent 6c547725
from library.models import *
from .models import *
from rest_framework import serializers
from django.contrib.auth import authenticate, get_user_model
class UserLoginSerializer(serializers.Serializer):
username = serializers.CharField()
password = serializers.CharField(write_only=True)
class Meta:
model = CustomUser
fields = ['username', 'password']
def validate(self, data):
username = data.get('username')
password = data.get('password')
if username and password:
user = authenticate(request=self.context.get('request'), username=username, password=password)
if not user:
msg = 'Unable to log in with provided credentials.'
raise serializers.ValidationError(msg, code='authorization')
data['user'] = user
else:
msg = 'Must include "username" and "password".'
raise serializers.ValidationError(msg, code='authorization')
return data
class UserLogoutSerializer(serializers.Serializer):
token = serializers.CharField()
class ChangePasswordSerializer(serializers.Serializer):
old_password = serializers.CharField(required=True)
new_password = serializers.CharField(required=True)
class MemberRegistrationSerializer(serializers.ModelSerializer):
class Meta:
model = CustomUser
fields = ['username', 'email', 'password']
extra_kwargs = {"password": {"write_only": True}}
def create(self, validated_data):
username=validated_data["username"]
email=validated_data["email"]
user = CustomUser(username=username, email=email)
user.set_password(validated_data["password"])
user.save()
return user
class LibrarianRegistrationSerializer(serializers.ModelSerializer):
class Meta:
model = CustomUser
fields = ['username', 'email', 'password', 'is_librarian']
extra_kwargs = {"password": {"write_only": True}}
def create(self, validated_data):
username=validated_data["username"]
email=validated_data["email"]
is_librarian=validated_data["is_librarian"]
user = CustomUser(username=username, email=email, is_librarian=is_librarian)
user.set_password(validated_data["password"])
user.save()
return user
class UserProfileSerializer(serializers.ModelSerializer):
class Meta:
model = CustomUser
fields = ['email', 'first_name', 'last_name']
class CategorySerializer(serializers.ModelSerializer):
class Meta:
......@@ -12,12 +80,30 @@ class BookSerializer(serializers.ModelSerializer):
model = Book
fields = '__all__'
class BookSearchSerializer(serializers.Serializer):
book_name = serializers.CharField(max_length=255)
class MemberSerializer(serializers.ModelSerializer):
class Meta:
model = Member
fields = '__all__'
class LibrarianSerializer(serializers.ModelSerializer):
class Meta:
model = Librarian
fields = '__all__'
class BookLoanSerializer(serializers.ModelSerializer):
class Meta:
model = BookLoan
fields = '__all__'
class OverdueLoanSerializer(serializers.ModelSerializer):
class Meta:
model = BookLoan
fields = '__all__'
class NearOutstandingLoanSerializer(serializers.ModelSerializer):
class Meta:
model = BookLoan
fields = '__all__'
\ No newline at end of file
......@@ -3,241 +3,304 @@ from django.views.decorators.csrf import csrf_exempt
from rest_framework.parsers import JSONParser
from library.models import *
from api.serializers import *
from datetime import date, timedelta
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status, generics
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.generics import CreateAPIView
from rest_framework.views import APIView
# from rest_framework.permissions import IsAuthenticated
from django.http import Http404
from rest_framework.pagination import PageNumberPagination
from django.db.models import F, ExpressionWrapper, fields
from rest_framework.permissions import IsAuthenticated
from rest_framework.authtoken.models import Token
from .permissions import *
from rest_framework_simplejwt.tokens import RefreshToken
from django.contrib.auth import authenticate, login, get_user_model
#set Pagination
class MyPageNumberPagination(PageNumberPagination):
page_size = 10
page_size_query_param = 'page_size'
max_page_size = 100
# @csrf_exempt
# @api_view(['GET', 'POST'])
# def book_list(request):
# """
# List all code snippets, or create a new snippet.
# """
# if request.method == 'GET':
# book = Member.objects.all()
# serializer = BookSerializer(book, many=True)
# return Response(serializer.data)
# elif request.method == 'POST':
# data = JSONParser().parse(request)
# serializer = BookSerializer(data=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)
# @api_view(['GET', 'PUT', 'DELETE'])
# def book_detail(request, pk):
# """
# Retrieve, update or delete a code snippet.
# """
# try:
# book = Book.objects.get(pk=pk)
# except Book.DoesNotExist:
# return Response(status=status.HTTP_404_NOT_FOUND)
# if request.method == 'GET':
# serializer = BookSerializer(book)
# return Response(serializer.data)
# elif request.method == 'PUT':
# serializer = BookSerializer(book, data=request.data)
# if serializer.is_valid():
# serializer.save()
# return Response(serializer.data)
# return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# elif request.method == 'DELETE':
# book.delete()
# return Response(status=status.HTTP_204_NO_CONTENT)
# @csrf_exempt
# @api_view(['GET', 'POST'])
# def member_list(request):
# """
# List all Member, or create a new Member.
# """
# if request.method == 'GET':
# member = Member.objects.all()
# serializer = MemberSerializer(member, many=True)
# return Response(serializer.data)
# elif request.method == 'POST':
# data = JSONParser().parse(request)
# serializer = MemberSerializer(data=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)
# @api_view(['GET', 'PUT', 'DELETE'])
# def member_detail(request, pk):
# """
# Retrieve, update or delete a code snippet.
# """
# try:
# member = Member.objects.get(pk=pk)
# except Member.DoesNotExist:
# return Response(status=status.HTTP_404_NOT_FOUND)
# if request.method == 'GET':
# serializer = MemberSerializer(member)
# return Response(serializer.data)
# elif request.method == 'PUT':
# serializer = MemberSerializer(member, data=request.data)
# if serializer.is_valid():
# serializer.save()
# return Response(serializer.data)
# return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# elif request.method == 'DELETE':
# member.delete()
# return Response(status=status.HTTP_204_NO_CONTENT)
# class Book_List(APIView):
# """
# List all Book, or create a new Book.
# """
# def get(self, request, format=None):
# book = Book.objects.all()
# serializer = BookSerializer(book, many=True)
# return Response(serializer.data)
# def post(self, request, format=None):
# serializer = BookSerializer(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)
# class Book_Detail(APIView):
# """
# Retrieve, update or delete a Book instance.
# """
# def get_object(self, pk):
# try:
# return Book.objects.get(pk=pk)
# except Book.DoesNotExist:
# raise Http404
# def get(self, request, pk, format=None):
# book = self.get_object(pk)
# serializer = BookSerializer(book)
# return Response(serializer.data)
# def put(self, request, pk, format=None):
# book = self.get_object(pk)
# serializer = BookSerializer(book, data=request.data)
# if serializer.is_valid():
# serializer.save()
# return Response(serializer.data)
# return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# def delete(self, request, pk, format=None):
# book = self.get_object(pk)
# book.delete()
# return Response(status=status.HTTP_204_NO_CONTENT)
# class Member_List(APIView):
# """
# List all Member, or create a new Member.
# """
# def get(self, request, format=None):
# member = Member.objects.all()
# serializer = MemberSerializer(member, many=True)
# return Response(serializer.data)
# def post(self, request, format=None):
# serializer = MemberSerializer(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)
# class Member_Detail(APIView):
# """
# Retrieve, update or delete a Member instance.
# """
# def get_object(self, pk):
# try:
# return Member.objects.get(pk=pk)
# except Member.DoesNotExist:
# raise Http404
# def get(self, request, pk, format=None):
# member = self.get_object(pk)
# serializer = MemberSerializer(member)
# return Response(serializer.data)
# def put(self, request, pk, format=None):
# member = self.get_object(pk)
# serializer = MemberSerializer(member, data=request.data)
# if serializer.is_valid():
# serializer.save()
# return Response(serializer.data)
# return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# def delete(self, request, pk, format=None):
# member = self.get_object(pk)
# member.delete()
# return Response(status=status.HTTP_204_NO_CONTENT)
# class BookLoan_List(APIView):
# """
# List all BookLoan, or create a new BookLoan.
# """
# def get(self, request, format=None):
# bookloan = BookLoan.objects.all()
# serializer = BookLoanSerializer(bookloan, many=True)
# return Response(serializer.data)
# def post(self, request, format=None):
# serializer = BookLoanSerializer(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)
#regist librarian
class LibrarianRegistrationAPIView(generics.CreateAPIView):
queryset = CustomUser.objects.all()
serializer_class = MemberRegistrationSerializer
#regist member
class MemberRegistrationAPIView(generics.ListCreateAPIView):
queryset = CustomUser.objects.all()
serializer_class = MemberRegistrationSerializer
# def create(self, request, *args, **kwargs):
# serializer = self.get_serializer(data=request.data)
# serializer.is_valid(raise_exception=True)
# user = serializer.save(is_member=True)
# login(request, user)
# response_data = {
# 'message': 'Member registered successfully',
# 'user_id': user.id,
# 'username': user.username,
# 'email': user.email,
# 'is_member': user.is_member,
# }
# return Response(response_data, status=status.HTTP_201_CREATED)
#login member
class MemberLoginView(APIView):
def post(self, request, *args, **kwargs):
username = request.data.get('username')
password = request.data.get('password')
user = authenticate(username=username, password=password)
if user is not None and user.is_member:
refresh = RefreshToken.for_user(user)
serializer = UserLoginSerializer(user)
return Response({
'refresh': str(refresh),
'access': str(refresh.access_token),
'user': serializer.data
}, status=status.HTTP_200_OK)
else:
return Response({'detail': 'Invalid credentials'}, status=status.HTTP_401_UNAUTHORIZED)
#login librarian
class LibrarianLoginView(APIView):
def post(self, request, *args, **kwargs):
username = request.data.get('username')
password = request.data.get('password')
user = authenticate(username=username, password=password)
if user is not None and user.is_librarian:
refresh = RefreshToken.for_user(user)
serializer = UserLoginSerializer(user)
return Response({
'refresh': str(refresh),
'access': str(refresh.access_token),
'user': serializer.data
}, status=status.HTTP_200_OK)
else:
return Response({'detail': 'Invalid credentials'}, status=status.HTTP_401_UNAUTHORIZED)
class MemberLogoutView(APIView):
permission_classes = [IsAuthenticated]
def post(self, request):
try:
if request.user.is_librarian:
return Response({'detail': 'invalid role user'}, status=status.HTTP_401_UNAUTHORIZED)
# Mengambil token refresh dari request
refresh_token = request.data["refresh"]
# Memblokir token refresh
token = RefreshToken(refresh_token)
token.blacklist()
return Response({"message": "Logout berhasil."}, status=status.HTTP_200_OK)
except Exception as e:
return Response({"error": str(e)}, status=status.HTTP_400_BAD_REQUEST)
#logout librarian
class LibrarianLogoutView(APIView):
permission_classes = [IsAuthenticated]
def post(self, request):
try:
if request.user.is_member:
return Response({'detail': 'invalid role user'}, status=status.HTTP_401_UNAUTHORIZED)
# Mengambil token refresh dari request
refresh_token = request.data["refresh"]
# Memblokir token refresh
token = RefreshToken(refresh_token)
token.blacklist()
return Response({"message": "Logout berhasil."}, status=status.HTTP_200_OK)
except Exception as e:
return Response({"error": str(e)}, status=status.HTTP_400_BAD_REQUEST)
#ganti password
class ChangePasswordView(APIView):
permission_classes = [IsAuthenticated]
def post(self, request):
serializer = ChangePasswordSerializer(data=request.data)
if serializer.is_valid():
# Periksa apakah password lama benar
user = request.user
old_password = serializer.data.get("old_password")
if not user.check_password(old_password):
return Response({"old_password": ["Password lama tidak sesuai."]}, status=status.HTTP_400_BAD_REQUEST)
# Setel password baru
new_password = serializer.data.get("new_password")
user.set_password(new_password)
user.save()
return Response({"message": "Password berhasil diganti."}, status=status.HTTP_200_OK)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class ChangeProfileView(generics.UpdateAPIView):
permission_classes = [IsAuthenticated]
serializer_class = UserProfileSerializer
def get_object(self):
return self.request.user
#Category Create dan List
class CategoryList(generics.ListCreateAPIView):
permission_classes = [LibrarianPermission]
queryset = Category.objects.all()
serializer_class = CategorySerializer
#Category Update, Detail, Delete
class CategoryDetail(generics.RetrieveUpdateDestroyAPIView):
permission_classes = [LibrarianPermission]
queryset = Category.objects.all()
serializer_class = CategorySerializer
#Book Create dan List
class BookList(generics.ListCreateAPIView):
permission_classes = [MemberReadOnlyPermission|LibrarianPermission]
queryset = Book.objects.all()
serializer_class = BookSerializer
#Book Update, Detail, Delete
class BookDetail(generics.RetrieveUpdateDestroyAPIView):
permission_classes = [MemberReadOnlyPermission|LibrarianPermission]
queryset = Book.objects.all()
serializer_class = BookSerializer
#Member List
class MemberList(generics.ListCreateAPIView):
permission_classes = [LibrarianPermission]
queryset = Member.objects.all()
serializer_class = MemberSerializer
#Member Update, Detail, Delete
class MemberDetail(generics.RetrieveUpdateDestroyAPIView):
permission_classes = [LibrarianPermission]
queryset = Member.objects.all()
serializer_class = MemberSerializer
#Librarian List
class LibrarianList(generics.ListCreateAPIView):
permission_classes = [LibrarianPermission]
queryset = Librarian.objects.all()
serializer_class = LibrarianSerializer
#Librarian Update, Detail, Delete
class LibrarianDetail(generics.RetrieveUpdateDestroyAPIView):
permission_classes = [LibrarianPermission]
queryset = Librarian.objects.all()
serializer_class = LibrarianSerializer
#BookLoan Create dan List
class BookLoanList(generics.ListCreateAPIView):
permission_classes = [LibrarianPermission]
queryset = BookLoan.objects.all()
serializer_class = BookLoanSerializer
pagination_class = MyPageNumberPagination
pagination_class = MyPageNumberPagination
#BookLoan Update, Detail, Delete
class BookLoanDetail(generics.RetrieveUpdateDestroyAPIView):
permission_classes = [LibrarianPermission]
queryset = BookLoan.objects.all()
serializer_class = BookLoanSerializer
\ No newline at end of file
serializer_class = BookLoanSerializer
class BookSearchView(generics.ListAPIView):
permission_classes = [MemberReadOnlyPermission|LibrarianPermission]
serializer_class = BookSerializer
def get_queryset(self):
book_name = self.request.query_params.get('book_name', '')
return Book.objects.filter(title__icontains=book_name)
#Book list By Year
class BookListByYear(generics.ListAPIView):
permission_classes = [MemberReadOnlyPermission|LibrarianPermission]
serializer_class = BookSerializer
def get_queryset(self):
year = self.kwargs['year']
return Book.objects.filter(date_publish=year)
#Book list By Year and Category
class BookListByYearAndCategory(generics.ListAPIView):
permission_classes = [MemberReadOnlyPermission|LibrarianPermission]
serializer_class = BookSerializer
def get_queryset(self):
year = self.kwargs['year']
category = self.kwargs['category']
return Book.objects.filter(date_publish=year, category__name=category)
#Book list By Category
class BookListByCategory(generics.ListAPIView):
permission_classes = [MemberReadOnlyPermission|LibrarianPermission]
serializer_class = BookSerializer
def get_queryset(self):
category = self.kwargs['category']
return Book.objects.filter(category__name=category)
#Outstanding Loan List
class NearOutstandingLoansAPIView(APIView):
permission_classes = [LibrarianPermission]
def get(self, request, format=None):
tomorrow = date.today() + timedelta(days=1)
near_outstanding_loans = tomorrow + timedelta(days=2)
near_date = BookLoan.objects.filter(due_date__gte=tomorrow, due_date__lte=near_outstanding_loans)
near_outstanding_loans = near_date.annotate(
time_difference=ExpressionWrapper(
F('due_date') - date.today(),
output_field=fields.DurationField()
)
)
serializer = NearOutstandingLoanSerializer(near_outstanding_loans, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
#overdue loan list
class OverdueLoansAPIView(APIView):
permission_classes = [LibrarianPermission]
def get(self, request, format=None):
overdue_loans = BookLoan.objects.filter(due_date__lte=date.today())
over_due = overdue_loans.annotate(
dead=ExpressionWrapper(
F('due_date') - date.today(),
output_field=fields.DurationField()
)
).exclude(is_returned=True)
for loan in over_due:
loan.dead = abs(loan.dead.days)
serializer = OverdueLoanSerializer(over_due, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
No preview for this file type
......@@ -5,7 +5,7 @@
<div class="card mb-4">
<div class="card-header">
<i class="fas fa-table me-1"></i>
Member List
Librarian List
</div>
<div class="card-body">
<table id="datatablesSimple">
......@@ -32,7 +32,7 @@
<td>{{ librarian.user.username }}</td>
<td>{{ librarian.user.email }}</td>
<td>
<a class="btn btn-secondary col-2 mx-2" href="{% url 'librarian_edit' pk=librarian.pk %}" role="button">Edit</a>
<a class="btn btn-secondary col-2 mx-2" href="{% url 'librarian_edit' id=librarian.id %}" role="button">Edit</a>
<a class="btn btn-danger col-2 mx-2" href="delete/{{librarian.id}}" role="button" onclick="return confirm('Are you sure you want to delete {{book.title}}?')">Delete</a>
</td>
</tr>
......@@ -40,11 +40,11 @@
</tbody>
</table>
<div>
<a class="btn btn-primary col-2 mx-3" href="{% url 'librarian_new' %}" role="button">Add a Librarian</a>
<a class="btn btn-primary col-1 mx-3" href="{% url 'librarian_new' %}" role="button">Add Librarian</a>
<a class="btn btn-primary col-2 mx-3" href="{% url 'librarian_login_history' %}" role="button">Librarian Login History</a>
</div>
</div>
</div>
</div>
{% endblock content%}
{% endblock content%}
\ No newline at end of file
......@@ -11,59 +11,35 @@
{% csrf_token %}
<div class="mb-3">
<label for="id_name">Name:</label>
<label for="id_name">First Name:</label>
<input type="text" name="name" id="id_name" placeholder="Input Name" class="form-control" required>
</div>
<div class="mb-3">
<label for="id_username">Username:</label>
<input type="text" name="username" id="id_username" placeholder="Username" class="form-control" required>
<label for="id_lname">Last Name:</label>
<input type="text" name="last_name" id="id_lname" placeholder="Input Name" class="form-control" required>
</div>
<div class="mb-3">
<label for="id_email">Email:</label>
<input type="email" name="email" id="id_email" placeholder="Email" class="form-control" required>
<label for="id_address" class="form-label">Address</label>
<textarea type="text" name="address" id="id_address" placeholder="Input Address" class="form-control" required></textarea>
</div>
<div class="mb-3">
<label for="id_password">Password:</label>
<input type="password" name="password1" id="id_password" placeholder="Password" class="form-control" required>
<label for="id_birth_place" class="form-label">Birth Place</label>
<input type="text" name="birth_place" id="id_birth_place" placeholder="Input Birth Place" class="form-control" required>
</div>
<div class="mb-3">
<label for="id_password2">Confirm Password:</label>
<input type="password" name="password2" id="id_password2" placeholder="Confirm Password" class="form-control" required>
<label for="id_date_birth" class="form-label">Birth Date</label>
<input type="date" name="date_birth" id="id_date_birth" placeholder="Input datebirth" class="form-control" required>
</div>
<div class="mb-3">
<label for="id_phone_number" class="form-label">Phone Number</label>
{{form.phone_number}}
</div>
<button type="submit" class="btn btn-primary" role="button">Add Librarian</button>
<a class="btn btn-warning col-2 mx-2" href="{% url 'librarian_list' %}"" role="button">Back</a>
</form>
</div>
</div>
</div>
</div>
</div>
<!-- <script>
function validateForm() {
var password = document.getElementById("id_password").value;
var confirmPassword = document.getElementById("id_confirm_password").value;
if (password !== confirmPassword) {
alert("Passwords do not match.");
return false;
}
return true;
}
</script> -->
<!-- <div style="text-align: center; margin-top: 50px;">
<h2>Add Librarian</h2>
<form method="post" action="{% url 'librarian_new' %}">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="btn btn-primary">Save</button>
</form>
</div> -->
{% endblock content%}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment