mirror of
https://github.com/i701/sarlink-portal-api.git
synced 2025-06-27 22:03:58 +00:00
Enhance User model: add email field with unique constraint, update id_card field to allow null values, and include verified field. Update UserAdmin to display verified field. Improve device listing to filter by logged-in user.
All checks were successful
Build and Push Docker Images / Build and Push Docker Images (push) Successful in 2m39s
All checks were successful
Build and Push Docker Images / Build and Push Docker Images (push) Successful in 2m39s
This commit is contained in:
116
api/views.py
116
api/views.py
@ -32,6 +32,17 @@ from .serializers import (
|
||||
CustomReadOnlyUserByIDCardSerializer,
|
||||
)
|
||||
|
||||
ID_CARD_PATTERN = r"^[A-Z]{1,2}[0-9]{6,7}$"
|
||||
MOBILE_PATTERN = r"^[7|9][0-9]{6}$"
|
||||
ACCOUNT_NUMBER_PATTERN = r"^(7\d{12}|9\d{16})$"
|
||||
|
||||
|
||||
class ErrorMessages:
|
||||
USERNAME_EXISTS = "Username already exists."
|
||||
INVALID_ID_CARD = "Please enter a valid ID card number."
|
||||
INVALID_MOBILE = "Please enter a valid mobile number."
|
||||
INVALID_ACCOUNT = "Please enter a valid account number."
|
||||
|
||||
|
||||
class CreateUserView(generics.CreateAPIView):
|
||||
# Create user API view
|
||||
@ -42,65 +53,39 @@ class CreateUserView(generics.CreateAPIView):
|
||||
def post(self, request, *args, **kwargs):
|
||||
# Extract required fields from request data
|
||||
password = request.data.get("password")
|
||||
username = request.data.get("username") # This can be None
|
||||
username = request.data.get("username")
|
||||
address = request.data.get("address")
|
||||
mobile = request.data.get("mobile")
|
||||
acc_no = request.data.get("acc_no")
|
||||
id_card = request.data.get("id_card")
|
||||
dob = request.data.get("dob")
|
||||
atoll_id = request.data.get("atoll") # Get the atoll ID
|
||||
island_id = request.data.get("island") # Get the island ID
|
||||
atoll_id = request.data.get("atoll")
|
||||
island_id = request.data.get("island")
|
||||
terms_accepted = request.data.get("terms_accepted")
|
||||
policy_accepted = request.data.get("policy_accepted")
|
||||
firstname = request.data.get("firstname")
|
||||
lastname = request.data.get("lastname")
|
||||
# Validate required fields
|
||||
|
||||
existing_username = User.objects.filter(username=username).first()
|
||||
if existing_username:
|
||||
return Response({"message": "Username already exists."}, status=400)
|
||||
# Validate required fields first
|
||||
validation_error = self.validate_required_fields(request.data)
|
||||
if validation_error:
|
||||
return validation_error
|
||||
|
||||
if not firstname:
|
||||
return Response({"message": "firstname is required."}, status=400)
|
||||
if not lastname:
|
||||
return Response({"message": "lastname is required."}, status=400)
|
||||
if not password:
|
||||
return Response({"message": "Password is required."}, status=400)
|
||||
if not username:
|
||||
return Response({"message": "Username is required."}, status=400)
|
||||
if not address:
|
||||
return Response({"message": "Address is required."}, status=400)
|
||||
if not mobile:
|
||||
return Response({"message": "Mobile number is required."}, status=400)
|
||||
if not acc_no:
|
||||
return Response({"message": "Account number is required."}, status=400)
|
||||
if not id_card:
|
||||
return Response({"message": "ID card is required."}, status=400)
|
||||
if not dob:
|
||||
return Response({"message": "Date of birth is required."}, status=400)
|
||||
if not atoll_id:
|
||||
return Response({"message": "Atoll is required."}, status=400)
|
||||
if not island_id:
|
||||
return Response({"message": "Island is required."}, status=400)
|
||||
if terms_accepted is None:
|
||||
return Response({"message": "Terms acceptance is required."}, status=400)
|
||||
if policy_accepted is None:
|
||||
return Response({"message": "Policy acceptance is required."}, status=400)
|
||||
# Check username uniqueness after validation
|
||||
if User.objects.filter(username=username).exists():
|
||||
return Response({"message": ErrorMessages.USERNAME_EXISTS}, status=400)
|
||||
|
||||
if not re.match(r"^[A-Z]{1,2}[0-9]{6,7}$", id_card):
|
||||
return Response(
|
||||
{"message": "Please enter a valid ID card number."}, status=400
|
||||
)
|
||||
if id_card and not re.match(ID_CARD_PATTERN, id_card):
|
||||
return Response({"message": ErrorMessages.INVALID_ID_CARD}, status=400)
|
||||
|
||||
if not re.match(r"^[7|9][0-9]{6}$", mobile):
|
||||
return Response(
|
||||
{"message": "Please enter a valid mobile number."}, status=400
|
||||
)
|
||||
if User.objects.filter(id_card=id_card).exists():
|
||||
return Response({"message": "ID card already exists."}, status=400)
|
||||
|
||||
if not re.match(r"^(7\d{12}|9\d{16})$", acc_no):
|
||||
return Response(
|
||||
{"message": "Please enter a valid account number."}, status=400
|
||||
)
|
||||
if mobile is None or not re.match(MOBILE_PATTERN, mobile):
|
||||
return Response({"message": ErrorMessages.INVALID_MOBILE}, status=400)
|
||||
|
||||
if acc_no is None or not re.match(ACCOUNT_NUMBER_PATTERN, acc_no):
|
||||
return Response({"message": ErrorMessages.INVALID_ACCOUNT}, status=400)
|
||||
|
||||
# Fetch Atoll and Island instances
|
||||
try:
|
||||
@ -111,19 +96,20 @@ class CreateUserView(generics.CreateAPIView):
|
||||
except Island.DoesNotExist:
|
||||
return Response({"message": "Island not found."}, status=404)
|
||||
|
||||
# Create user without email
|
||||
# Create user
|
||||
user = User.objects.create_user(
|
||||
first_name=firstname,
|
||||
last_name=lastname,
|
||||
username=username,
|
||||
username=str(username),
|
||||
password=password,
|
||||
email=None,
|
||||
address=address,
|
||||
mobile=mobile,
|
||||
acc_no=acc_no,
|
||||
id_card=id_card,
|
||||
dob=dob,
|
||||
atoll=atoll, # Assign the Atoll instance
|
||||
island=island, # Assign the Island instance
|
||||
atoll=atoll,
|
||||
island=island,
|
||||
terms_accepted=terms_accepted,
|
||||
policy_accepted=policy_accepted,
|
||||
)
|
||||
@ -133,6 +119,32 @@ class CreateUserView(generics.CreateAPIView):
|
||||
serializer.data, status=status.HTTP_201_CREATED, headers=headers
|
||||
)
|
||||
|
||||
def validate_required_fields(self, data):
|
||||
required_fields = {
|
||||
"firstname": "First name",
|
||||
"lastname": "Last name",
|
||||
"password": "Password",
|
||||
"username": "Username",
|
||||
"address": "Address",
|
||||
"mobile": "Mobile number",
|
||||
"acc_no": "Account number",
|
||||
"id_card": "ID card",
|
||||
"dob": "Date of birth",
|
||||
"atoll": "Atoll",
|
||||
"island": "Island",
|
||||
}
|
||||
|
||||
for field, label in required_fields.items():
|
||||
if not data.get(field):
|
||||
return Response({"message": f"{label} is required."}, status=400)
|
||||
|
||||
if data.get("terms_accepted") is None:
|
||||
return Response({"message": "Terms acceptance is required."}, status=400)
|
||||
if data.get("policy_accepted") is None:
|
||||
return Response({"message": "Policy acceptance is required."}, status=400)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
class LoginView(KnoxLoginView):
|
||||
# login view extending KnoxLoginView
|
||||
@ -216,7 +228,11 @@ def filter_user(request):
|
||||
print(f"Querying with filters: {filters}")
|
||||
print(f"Found user: {user}")
|
||||
|
||||
return Response({"ok": True if user else False})
|
||||
return Response(
|
||||
{"ok": True, "verified": user.verified}
|
||||
if user
|
||||
else {"ok": False, "verified": False}
|
||||
)
|
||||
|
||||
|
||||
class ListUserByIDCardView(generics.ListAPIView):
|
||||
|
Reference in New Issue
Block a user