У меня есть запрос, который проверяет, существует ли BVN или Phone _number в моей базе данных, но я пытаюсь добавить третий элемент, который является каналом, используемым пользователем.
Я работаю над API, который принимает BVN или номер телефона и канал от пользователя. Когда они вызывают API, я должен вернуть сообщение, основанное на канале (если они использовали, я верну текст, а если они использовали мобильный банк, я верну html). То, что я создал на данный момент, будет проверять выбор любого из BVN или PHone номеров и проверять канал. Если пользователь был сохранен ранее, я возвращаю "пользователь существует", если нет, я сохраню. Если пользователь с номером телефона "X" дважды обращается к API с разными каналами, я хочу, чтобы он прошел. Я хочу запретить доступ только если (номер телефона или bvn) и канал соответствуют желаемому в базе данных.
Serializer.py `
class SaveTermsSerializer(serializers.ModelSerializer):
channel=serializers.CharField(required=True)
bvn= serializers.CharField(max_length=15,allow_blank=True, required=False)
phone_number=PhoneNumberField(allow_blank=True, required=False)
# terms_status=serializers.CharField(max_length=25)
class Meta:
model = Consent
fields = ['channel','phone_number', 'bvn', 'consent_status']
def validate(self, data):
bvn = data.get('bvn')
channel = data.get('channel')
phone_number = data.get('phone_number')
if channel.lower() not in ['ussd','mobile_banking','online_banking']:
raise serializers.ValidationError("Invalid channel detected")
if not (bvn or phone_number):
raise serializers.ValidationError("BVN and Phone Number cannot be empty")
if bvn and not bvn.isdigit():
raise serializers.ValidationError("BVN can only be numbers")
if bvn or phone_number:
response = Consent.objects.filter(Q(bvn=bvn) | Q(phone_number=phone_number) and channel).exists()
if response:
consent_response = {
'status' : "User has accepted terms already",
'consent_data' : data
}
else:
channel = channel.lower()
message = Message.objects.get(channel=channel)
consent_response = {
'status' : message.consent_message,
'consent_data' : data
}
return consent_response
def create(self, validated_data):
data = validated_data.get('consent_data')
bvn = data.get('bvn') if data.get('bvn') else None
phone_number = data.get('phone_number') if data.get('phone_number') else None
channel = data.get('channel')
consent_status = data.get('consent_status')
queryset = Consent.objects.create(bvn=bvn,phone_number=phone_number,consent_status = consent_status, channel=channel)
return queryset
`
Views.py:
`
class SaveUsers(generics.GenericAPIView):
serializer_class = serializers.SaveTermsSerializer
permission_classes = (IsAuthenticated,)
consents = Consent()
def post(self, request):
data = request.data
try:
serialized_data = self.serializer_class(data = data)
if serialized_data.is_valid(raise_exception=True):
serialized_data.save()
return Response({"Message" : "User has been saved successfully", "Status":"Success"}, status=status.HTTP_200_OK)
else:
return Response({"Message" :" User already accepted the terms", "Status":"Failed"},status=status.HTTP_400_BAD_REQUEST)
except django.db.utils.IntegrityError:
return Response({"Message" :" User already accepted the terms", "Status":"Success"},status=status.HTTP_400_BAD_REQUEST)
`
model.py:
`
SELECT_CHANNEL=(
('USSD','ussd'),
('ONLINE_BANKING','online_banking'),
('MOBILE_BANKING','mobile_banking'),
)
CONSENT_STATUSES=(
('ACCEPTED','accepted'),
('DECLINED','declined')
)
# Create your models here.
class Consent(models.Model):
consent_status=models.CharField(max_length=25, choices=CONSENT_STATUSES, null=False, blank=False)
channel=models.CharField(max_length=25, null=False,choices=SELECT_CHANNEL)
bvn= models.CharField(max_length=15,unique=True,null=True)
phone_number=models.CharField(unique=True,null=True,max_length=20)
def __str__(self):
return f"<{self.bvn} {self.phone_number} : {self.channel}>"
class Message(models.Model):
consent_message= models.TextField(null=False, blank=False)
channel=models.CharField(max_length=25, null=True,choices=SELECT_CHANNEL)
`