Commit 3d6b2f9a authored by Nurrofimutaqin's avatar Nurrofimutaqin

push perbaruan app

parent cb606779
...@@ -14,17 +14,26 @@ class BookSerializer(serializers.ModelSerializer): ...@@ -14,17 +14,26 @@ class BookSerializer(serializers.ModelSerializer):
fields = '__all__' fields = '__all__'
class BookLoanSerializer(serializers.ModelSerializer): class BookLoanSerializer(serializers.ModelSerializer):
member_nama = serializers.CharField(source='member.username', read_only=True)
buku_judul = serializers.CharField(source='buku.judul', read_only=True)
class Meta: class Meta:
model = Peminjaman model = Peminjaman
fields = '__all__' fields = ['id', 'tanggal_pinjam', 'tanggal_kembali', 'tanggal_pengembalian', 'status', 'member_nama', 'buku_judul']
class BookLoanUserSerializer(serializers.ModelSerializer): class BookLoanUserSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Peminjaman model = Peminjaman
fields = ['buku', 'tanggal_kembali'] fields = ['buku', 'tanggal_kembali']
class BookLoanByBukuSerializer(serializers.ModelSerializer):
class Meta:
model = Peminjaman
fields = ['tanggal_kembali']
class OverDueSerializer(serializers.ModelSerializer): class OverDueSerializer(serializers.ModelSerializer):
days_overdue = serializers.SerializerMethodField() days_overdue = serializers.SerializerMethodField()
member_nama = serializers.CharField(source='member.username', read_only=True)
buku_judul = serializers.CharField(source='buku.judul', read_only=True)
class Meta: class Meta:
model = Peminjaman model = Peminjaman
fields = '__all__' fields = '__all__'
...@@ -36,6 +45,8 @@ class OverDueSerializer(serializers.ModelSerializer): ...@@ -36,6 +45,8 @@ class OverDueSerializer(serializers.ModelSerializer):
class NearOverDueSerializer(serializers.ModelSerializer): class NearOverDueSerializer(serializers.ModelSerializer):
sisa_waktu = serializers.SerializerMethodField() sisa_waktu = serializers.SerializerMethodField()
member_nama = serializers.CharField(source='member.username', read_only=True)
buku_judul = serializers.CharField(source='buku.judul', read_only=True)
class Meta: class Meta:
model = Peminjaman model = Peminjaman
fields = '__all__' fields = '__all__'
...@@ -54,8 +65,7 @@ class NearOverDueSerializer(serializers.ModelSerializer): ...@@ -54,8 +65,7 @@ class NearOverDueSerializer(serializers.ModelSerializer):
class CustomUserSerializer(serializers.ModelSerializer): class CustomUserSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = CustomUser model = CustomUser
fields = ['username','password', 'role'] fields = ['id','username','email','first_name','last_name', 'role']
extra_kwargs = {"password": {"write_only": True}}
class UserSerializer(ModelSerializer): class UserSerializer(ModelSerializer):
......
...@@ -14,7 +14,7 @@ urlpatterns = [ ...@@ -14,7 +14,7 @@ urlpatterns = [
path('categorys/<int:pk>/', views.CategoryDetail.as_view()), path('categorys/<int:pk>/', views.CategoryDetail.as_view()),
path('book-loans/', views.BookLoanList.as_view()), path('book-loans/', views.BookLoanList.as_view()),
path('book-loans/<int:pk>/', views.BookLoanDetail.as_view()), path('book-loans/<int:pk>/', views.BookLoanDetail.as_view()),
path('users/', views.UserList.as_view()), # path('users/', views.UserList.as_view()),
# path('users/<int:pk>/', views.UserDetail.as_view()), # path('users/<int:pk>/', views.UserDetail.as_view()),
path('book-loans/near-overdue/', views.NearOverdueViewSet.as_view({'get': 'list'})), path('book-loans/near-overdue/', views.NearOverdueViewSet.as_view({'get': 'list'})),
path('book-loans/overdue/', views.OverdueViewSet.as_view({'get': 'list'})), path('book-loans/overdue/', views.OverdueViewSet.as_view({'get': 'list'})),
...@@ -24,7 +24,7 @@ urlpatterns = [ ...@@ -24,7 +24,7 @@ urlpatterns = [
path('token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), path('token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
path('token/verify/', TokenVerifyView.as_view(), name='token_verify '), path('token/verify/', TokenVerifyView.as_view(), name='token_verify '),
path('filter-book/judul/', views.BookListFilterByJudul.as_view(), name='filter-book-judul'), path('filter-book/judul/', views.BookListFilterByJudul.as_view(), name='filter-book-judul'),
path('filter-book/category_year/', views.BookFilterByCategory_Year.as_view(), name='filter-book'), path('filter-book/category/', views.BookFilterByCategory_Year.as_view(), name='filter-book'),
#registrasi #registrasi
path('registration/', views.RegistUser.as_view()), path('registration/', views.RegistUser.as_view()),
...@@ -42,6 +42,9 @@ urlpatterns = [ ...@@ -42,6 +42,9 @@ urlpatterns = [
path('change-password/', views.ChangePasswordAllView.as_view(), name='change-password-All'),
path('logout/', views.LogoutAllView.as_view(), name='logout'),
path('login/', views.LoginToAll.as_view()),
#pakai rest framework aja dan tidak dipakai #pakai rest framework aja dan tidak dipakai
...@@ -50,6 +53,9 @@ urlpatterns = [ ...@@ -50,6 +53,9 @@ urlpatterns = [
path('member/book-loans/', views.BookLoansUser.as_view(), name='member-book-loans'), path('member/book-loans/', views.BookLoansUser.as_view(), name='member-book-loans'),
path('member/book-loan-by-buku/<int:id>', views.BookLoanByBuku.as_view(), name='member-book-loans'),
path('book-loans/user/', views.BookLoanListByUser.as_view(), name='loans-user'),
] ]
urlpatterns = format_suffix_patterns(urlpatterns) urlpatterns = format_suffix_patterns(urlpatterns)
\ No newline at end of file
...@@ -27,15 +27,16 @@ from django.contrib.auth import authenticate ...@@ -27,15 +27,16 @@ from django.contrib.auth import authenticate
from rest_framework_simplejwt.tokens import RefreshToken from rest_framework_simplejwt.tokens import RefreshToken
class LargeResultsSetPagination(PageNumberPagination): class LargeResultsSetPagination(PageNumberPagination):
page_size = 5 page_size = 20
page_size_query_param = 'page_size' page_size_query_param = 'page_size'
class BookList(generics.ListCreateAPIView): class BookList(generics.ListCreateAPIView):
permission_classes = [IsAuthenticated]
queryset = Book.objects.all() queryset = Book.objects.all()
serializer_class = BookSerializer serializer_class = BookSerializer
pagination_class = LargeResultsSetPagination pagination_class = LargeResultsSetPagination
permission_classes = [IsAuthenticated]
##register ##register
...@@ -52,23 +53,27 @@ class CategoryList(generics.ListCreateAPIView): ...@@ -52,23 +53,27 @@ class CategoryList(generics.ListCreateAPIView):
serializer_class = CategorySerializer serializer_class = CategorySerializer
class CategoryDetail(generics.RetrieveUpdateDestroyAPIView): class CategoryDetail(generics.RetrieveUpdateDestroyAPIView):
permission_classes = [IsAuthenticated]
queryset = CategoryBook.objects.all() queryset = CategoryBook.objects.all()
serializer_class = CategorySerializer serializer_class = CategorySerializer
class BookLoanList(generics.ListCreateAPIView): class BookLoanList(generics.ListCreateAPIView):
permission_classes = [IsAuthenticated]
queryset = Peminjaman.objects.all() queryset = Peminjaman.objects.all()
serializer_class = BookLoanSerializer serializer_class = BookLoanSerializer
pagination_class = LargeResultsSetPagination pagination_class = LargeResultsSetPagination
class BookLoanDetail(generics.RetrieveUpdateDestroyAPIView): class BookLoanDetail(generics.RetrieveUpdateDestroyAPIView):
permission_classes = [IsAuthenticated]
queryset = Peminjaman.objects.all() queryset = Peminjaman.objects.all()
serializer_class = BookLoanSerializer serializer_class = BookLoanSerializer
class UserList(generics.ListCreateAPIView): # class UserList(generics.ListCreateAPIView):
queryset = CustomUser.objects.all() # permission_classes = [IsAuthenticated]
serializer_class = UserSerializer # queryset = CustomUser.objects.all()
# serializer_class = UserSerializer
# class UserDetail(generics.RetrieveUpdateDestroyAPIView): # class UserDetail(generics.RetrieveUpdateDestroyAPIView):
# queryset = get_user_model() # queryset = get_user_model()
...@@ -76,7 +81,7 @@ class UserList(generics.ListCreateAPIView): ...@@ -76,7 +81,7 @@ class UserList(generics.ListCreateAPIView):
class NearOverdueViewSet(viewsets.ReadOnlyModelViewSet): class NearOverdueViewSet(viewsets.ReadOnlyModelViewSet):
serializer_class = NearOverDueSerializer serializer_class = NearOverDueSerializer
pagination_class = LargeResultsSetPagination # pagination_class = LargeResultsSetPagination
def get_queryset(self): def get_queryset(self):
# Ambil data peminjaman buku yang hampir deadline (misalnya, 3 hari lagi) # Ambil data peminjaman buku yang hampir deadline (misalnya, 3 hari lagi)
tomorow = date.today() + timedelta(days=1) tomorow = date.today() + timedelta(days=1)
...@@ -87,7 +92,7 @@ class NearOverdueViewSet(viewsets.ReadOnlyModelViewSet): ...@@ -87,7 +92,7 @@ class NearOverdueViewSet(viewsets.ReadOnlyModelViewSet):
class OverdueViewSet(viewsets.ReadOnlyModelViewSet): class OverdueViewSet(viewsets.ReadOnlyModelViewSet):
serializer_class = OverDueSerializer serializer_class = OverDueSerializer
pagination_class = LargeResultsSetPagination # pagination_class = LargeResultsSetPagination
def get_queryset(self): def get_queryset(self):
overdue = Peminjaman.objects.filter(tanggal_kembali__lte=date.today(), status=False) overdue = Peminjaman.objects.filter(tanggal_kembali__lte=date.today(), status=False)
return overdue return overdue
...@@ -105,8 +110,8 @@ class MemberLoginView(ObtainAuthToken): ...@@ -105,8 +110,8 @@ class MemberLoginView(ObtainAuthToken):
class MemberProfileView(APIView): class MemberProfileView(APIView):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
customuser = request.customuser customuser = request.user
if customuser.role == 'member': if customuser is not None:
serializer = CustomUserSerializer(customuser) serializer = CustomUserSerializer(customuser)
return Response(serializer.data) return Response(serializer.data)
else: else:
...@@ -122,7 +127,7 @@ class BookFilterByCategory_Year(generics.ListAPIView): ...@@ -122,7 +127,7 @@ class BookFilterByCategory_Year(generics.ListAPIView):
queryset = Book.objects.all() queryset = Book.objects.all()
serializer_class = BookSerializer serializer_class = BookSerializer
filter_backends = [DjangoFilterBackend] filter_backends = [DjangoFilterBackend]
filterset_fields = ['categorybook__namaCategory', 'tahun_terbit'] filterset_fields = ['categorybook__namaCategory']
...@@ -263,7 +268,64 @@ class ChangePasswordLibrarianView(APIView): ...@@ -263,7 +268,64 @@ class ChangePasswordLibrarianView(APIView):
return Response({'detail': 'Kata sandi berhasil diubah.'}, status=status.HTTP_200_OK) return Response({'detail': 'Kata sandi berhasil diubah.'}, status=status.HTTP_200_OK)
#untuk semua user member dan librarian
class LogoutAllView(APIView):
permission_classes = [IsAuthenticated]
def post(self, request):
try:
# Hapus token akses
refresh_token = request.data.get('refresh')
token = RefreshToken(refresh_token)
token.blacklist()
return Response({'detail': 'Logout berhasil'}, status=status.HTTP_200_OK)
except Exception as e:
return Response({'detail': str(e)}, status=status.HTTP_400_BAD_REQUEST)
class LoginToAll(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:
refresh = RefreshToken.for_user(user)
serializer = CustomUserSerializer(user)
return Response({
'refresh': str(refresh),
'access': str(refresh.access_token),
'user': serializer.data
}, status=status.HTTP_200_OK)
else:
return Response({'detail': 'Invalid Username and Password'}, status=status.HTTP_401_UNAUTHORIZED)
class ChangePasswordAllView(APIView):
permission_classes = (IsAuthenticated,)
def post(self, request):
serializer = ChangePasswordSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = request.user
old_password = serializer.validated_data['old_password']
new_password = serializer.validated_data['new_password']
# Validasi kata sandi lama
if not user.check_password(old_password):
return Response({'detail': 'Kata sandi lama tidak valid.'}, status=status.HTTP_400_BAD_REQUEST)
# Ubah kata sandi
user.set_password(new_password)
user.save()
# Matikan token akses yang lama
refresh = RefreshToken.for_user(user)
refresh.blacklist()
return Response({'detail': 'Kata sandi berhasil diubah.'}, status=status.HTTP_200_OK)
class MemberProfileUpdateView(APIView): class MemberProfileUpdateView(APIView):
permission_classes = (IsAuthenticated,) permission_classes = (IsAuthenticated,)
...@@ -280,15 +342,60 @@ class MemberProfileUpdateView(APIView): ...@@ -280,15 +342,60 @@ class MemberProfileUpdateView(APIView):
serializer.save() serializer.save()
return Response(serializer.data, status=status.HTTP_200_OK) return Response(serializer.data, status=status.HTTP_200_OK)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def get(self, request):
user = request.user
# member = Member.objects.get(user=user)
serializer = MemberProfileUpdateSerializer(user)
return Response(serializer.data)
class BookLoansUser(generics.ListCreateAPIView): class BookLoansUser(generics.ListCreateAPIView):
queryset = Peminjaman.objects.all()
serializer_class = BookLoanUserSerializer serializer_class = BookLoanUserSerializer
permission_classes = [IsAuthenticated] permission_classes = [IsAuthenticated]
# def perform_create(self, serializer):
# serializer.save(member=self.request.user)
def post(self, request):
serializer = BookLoanByBukuSerializer(data=request.data)
id = request.data.get('buku')
# Cek apakah buku dengan ID yang diberikan ada di database
try:
buku = Book.objects.get(id=id)
except Book.DoesNotExist:
return Response({'detail': 'Buku dengan ID tersebut tidak ditemukan'}, status=status.HTTP_404_NOT_FOUND)
if Peminjaman.objects.filter(buku=id, status=False).exists():
return Response({'detail': 'Buku tidak tersedia karena belum dikembalikan!!'}, status=status.HTTP_400_BAD_REQUEST)
if serializer.is_valid():
# Simpan peminjaman
serializer.save(buku=buku, member=request.user)
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def get_queryset(self):
return Peminjaman.objects.filter(member=self.request.user)
class BookLoanByBuku(generics.ListCreateAPIView):
permission_classes = (IsAuthenticated,)
serializer_class = BookLoanSerializer
def post(self, request, id):
serializer = BookLoanByBukuSerializer(data=request.data)
buku = Book.objects.get(id=id)
if Peminjaman.objects.filter(buku=buku, status=False).exists():
return Response({'detail': 'Buku tidak tersedia karna belum dikembalikan!!'}, status=status.HTTP_400_BAD_REQUEST)
if serializer.is_valid():
serializer.save(buku=buku, member=request.user)
return Response(serializer.data, status=status.HTTP_200_OK)
def perform_create(self, serializer):
serializer.save(member=self.request.user)
def get_queryset(self): def get_queryset(self):
# Mengambil data peminjaman yang sesuai dengan user yang sedang login
return Peminjaman.objects.filter(member=self.request.user) return Peminjaman.objects.filter(member=self.request.user)
class BookLoanListByUser(generics.ListAPIView):
permission_classes = (IsAuthenticated,)
serializer_class = BookLoanSerializer
def get_queryset(self):
return Peminjaman.objects.filter(member=self.request.user)
...@@ -61,12 +61,9 @@ ...@@ -61,12 +61,9 @@
<td>{{books.tahun_terbit}}</td> <td>{{books.tahun_terbit}}</td>
<td>{{books.categorybook.namaCategory}}</td> <td>{{books.categorybook.namaCategory}}</td>
<td> <td>
<a href="detail/{{books.id}}" class="btn btn-secondary "> <a href="detail/{{books.id}}" class="btn btn-info ">
<i class="fas fa-fw fa-info"></i><span class="text"> Detail</span> <i class="fas fa-fw fa-info"></i><span class="text"> Detail</span>
</a> </a>
<a href="peminjaman/{{books.id}}" class="btn btn-secondary ">
<i class="fas fa-fw fa-info"></i><span class="text"> peminjaman</span>
</a>
{% if request.user.is_authenticated and request.user.role == 'librarian'%} {% if request.user.is_authenticated and request.user.role == 'librarian'%}
<a href="edit/{{books.id}}" class="btn btn-warning "> <a href="edit/{{books.id}}" class="btn btn-warning ">
<i class="fas fa-fw fa-edit"></i><span class="text"> Edit</span> <i class="fas fa-fw fa-edit"></i><span class="text"> Edit</span>
...@@ -74,6 +71,10 @@ ...@@ -74,6 +71,10 @@
<a href="delete/{{books.id}}" onclick="return confirm('aapakah anda yakin?')" class="btn btn-danger "> <a href="delete/{{books.id}}" onclick="return confirm('aapakah anda yakin?')" class="btn btn-danger ">
<i class="fas fa-fw fa-trash"></i><span class="text"> Delete</span> <i class="fas fa-fw fa-trash"></i><span class="text"> Delete</span>
</a> </a>
{%else%}
<a href="peminjaman/{{books.id}}" class="btn btn-success ">
<i class="fas fa-fw fa-save"></i><span class="text"> peminjaman</span>
</a>
{% endif %} {% endif %}
</td> </td>
</tr> </tr>
......
...@@ -27,7 +27,7 @@ SECRET_KEY = 'django-insecure-g7+t69de0ztz2(6_9r&d%gyf!f0o=!fq$_!8k&alx+-$0$-hfw ...@@ -27,7 +27,7 @@ SECRET_KEY = 'django-insecure-g7+t69de0ztz2(6_9r&d%gyf!f0o=!fq$_!8k&alx+-$0$-hfw
# SECURITY WARNING: don't run with debug turned on in production! # SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True DEBUG = True
ALLOWED_HOSTS = [] ALLOWED_HOSTS = ["10.0.2.2", "127.0.0.1" ]
# Application definition # Application definition
...@@ -155,7 +155,7 @@ REST_FRAMEWORK = { ...@@ -155,7 +155,7 @@ REST_FRAMEWORK = {
} }
SIMPLE_JWT = { SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=30), 'ACCESS_TOKEN_LIFETIME': timedelta(days=1),
'REFRESH_TOKEN_LIFETIME': timedelta(hours=1), 'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
'AUTH_HEADER_TYPES': ('Bearer',), 'AUTH_HEADER_TYPES': ('Bearer',),
} }
\ 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