This commit is contained in:
2026-02-26 11:06:14 +07:00
parent a397405f65
commit 1bf515ae76
29 changed files with 926 additions and 0 deletions
View File
+3
View File
@@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.
+5
View File
@@ -0,0 +1,5 @@
from django.apps import AppConfig
class LocationConfig(AppConfig):
name = 'location'
+40
View File
@@ -0,0 +1,40 @@
from django.db import models
from django.contrib.auth.models import User
from django_softdelete.models import SoftDeleteModel
class Province(SoftDeleteModel):
code = models.CharField(max_length=2, null=False, unique=True)
name = models.CharField(max_length=255, null=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name
class RegencyCity(SoftDeleteModel):
code = models.CharField(max_length=4, null=False, unique=True)
name = models.CharField(max_length=255, null=False)
province = models.ForeignKey(Province, on_delete=models.CASCADE, null=False)
def __str__(self):
return self.name
class Meta:
unique_together = ('code', 'province')
class Location(SoftDeleteModel):
name = models.CharField(max_length=255, null=False)
path = models.TextField(null=True, blank=True)
totem_latitude = models.DecimalField(max_digits=9, decimal_places=6, null=True, blank=True)
totem_longitude = models.DecimalField(max_digits=9, decimal_places=6, null=True, blank=True)
totem_code = models.CharField(max_length=50, null=True, blank=True)
province = models.ForeignKey(Province, on_delete=models.SET_NULL, null=True)
regency_city = models.ForeignKey(RegencyCity, on_delete=models.SET_NULL, null=True)
active = models.BooleanField(default=True)
def __str__(self):
return f"{self.user.username} - {self.province.name if self.province else 'No Province'} - {self.regency_city.name if self.regency_city else 'No Regency/City'}"
+35
View File
@@ -0,0 +1,35 @@
from rest_framework import serializers
from location import models
class ProvinceSerializer(serializers.ModelSerializer):
class Meta:
model = models.Province
fields = ['id', 'code', 'name']
class RegencyCitySerializer(serializers.ModelSerializer):
class Meta:
model = models.RegencyCity
fields = ['id', 'code', 'name', 'province']
class RegencyCityDetailSerializer(serializers.ModelSerializer):
province = ProvinceSerializer(read_only=True)
class Meta:
model = models.RegencyCity
fields = ['id', 'code', 'name', 'province']
class LocationSerializer(serializers.ModelSerializer):
class Meta:
model = models.Location
fields = ['id', 'name', 'path', 'totem_latitude', 'totem_longitude', 'totem_code', 'province', 'regency_city', 'active']
class LocationDetailSerializer(serializers.ModelSerializer):
province = ProvinceSerializer(read_only=True)
regency_city = RegencyCitySerializer(read_only=True)
class Meta:
model = models.Location
fields = ['id', 'name', 'path', 'totem_latitude', 'totem_longitude', 'totem_code', 'province', 'regency_city', 'active']
+3
View File
@@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.
+16
View File
@@ -0,0 +1,16 @@
from django.urls import path
from rest_framework.urlpatterns import format_suffix_patterns
from location import views
urlpatterns = [
path('provinces/', views.ProvinceList.as_view()),
path('provinces/<int:pk>/', views.ProvinceDetail.as_view()),
path('regencies_cities/', views.RegencyCityList.as_view()),
path('regencies_cities/<int:pk>/', views.RegencyCityDetail.as_view()),
path('locations/', views.LocationList.as_view()),
path('locations/<int:pk>/', views.LocationDetail.as_view()),
]
urlpatterns = format_suffix_patterns(urlpatterns)
+107
View File
@@ -0,0 +1,107 @@
from django.shortcuts import render
from rest_framework import generics, filters, permissions
from django_filters.rest_framework import DjangoFilterBackend
from location import models, serializers
# PROVINCES
class ProvinceList(generics.ListCreateAPIView):
queryset = models.Province.objects.all()
serializer_class = serializers.ProvinceSerializer
filter_backends = [filters.SearchFilter, filters.OrderingFilter, DjangoFilterBackend]
search_fields = ['name', 'code']
filterset_fields = ['name', 'code']
ordering_fields = '__all__'
def get_permissions(self):
if self.request.method == 'POST':
return [permissions.IsAdminUser()]
return [permissions.IsAuthenticated()]
class ProvinceDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = models.Province.objects.all()
serializer_class = serializers.ProvinceSerializer
def get_permissions(self):
if self.request.method == 'PUT' or self.request.method == 'DELETE':
return [permissions.IsAdminUser()]
return [permissions.IsAuthenticated()]
# REGENCY/CITY
class RegencyCityList(generics.ListCreateAPIView):
queryset = models.RegencyCity.objects.all()
serializer_class = serializers.RegencyCitySerializer
filter_backends = [filters.SearchFilter, filters.OrderingFilter, DjangoFilterBackend]
search_fields = ['name', 'code']
filterset_fields = ['name', 'code', 'province']
ordering_fields = '__all__'
def get_serializer_class(self):
serializer_class = self.serializer_class
if self.request.method == 'GET':
serializer_class = serializers.RegencyCityDetailSerializer
return serializer_class
def get_permissions(self):
if self.request.method == 'POST':
return [permissions.IsAdminUser()]
return [permissions.IsAuthenticated()]
class RegencyCityDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = models.RegencyCity.objects.all()
serializer_class = serializers.RegencyCitySerializer
def get_serializer_class(self):
serializer_class = self.serializer_class
if self.request.method == 'GET':
serializer_class = serializers.RegencyCityDetailSerializer
return serializer_class
def get_permissions(self):
if self.request.method == 'PUT' or self.request.method == 'DELETE':
return [permissions.IsAdminUser()]
return [permissions.IsAuthenticated()]
# LOCATION
class LocationList(generics.ListCreateAPIView):
queryset = models.Location.objects.all()
serializer_class = serializers.LocationSerializer
filter_backends = [filters.SearchFilter, filters.OrderingFilter, DjangoFilterBackend]
search_fields = ['name', 'path']
filterset_fields = ['name', 'path', 'totem_code', 'province', 'regency_city', 'active']
ordering_fields = '__all__'
def get_serializer_class(self):
serializer_class = self.serializer_class
if self.request.method == 'GET':
serializer_class = serializers.LocationDetailSerializer
return serializer_class
def get_permissions(self):
if self.request.method == 'POST':
return [permissions.IsAdminUser()]
return [permissions.IsAuthenticated()]
class LocationDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = models.Location.objects.all()
serializer_class = serializers.LocationSerializer
def get_serializer_class(self):
serializer_class = self.serializer_class
if self.request.method == 'GET':
serializer_class = serializers.LocationDetailSerializer
return serializer_class
def get_permissions(self):
if self.request.method == 'PUT' or self.request.method == 'DELETE':
return [permissions.IsAdminUser()]
return [permissions.IsAuthenticated()]