So I am creating a notification API. I have a broad cast model and client model, the client model has a tag field and an operator code field. I wan to be able to filter by tags and operator code fields and include them to the broadcast serializer during creation.
class Client(models.Model):
phoneRegex = RegexValidator(regex='^7[0-9]{10}$')
phone = models.CharField(validators=[phoneRegex], max_length=11, unique=True)
tag = TaggableManager()
def __str__(self):
return self.phone
@property
def operator_code(self):
return self.phone[1:4]
@property
def time_zone(self):
ru_number = phonenumbers.parse(self.phone, 'RU')
time_zone = timezone.time_zones_for_number(ru_number)
return time_zone
class Broadcast(models.Model):
date_created = models.DateTimeField(auto_now_add=True)
date_modified = models.DateTimeField(auto_now=True)
text = models.TextField(max_length=500)
end_date = models.DateTimeField()
def __str__(self):
return self.text
Serializers.py
class ClientSerializer(TaggitSerializer, serializers.ModelSerializer):
tag = TagListSerializerField()
time_zone = serializers.SerializerMethodField()
operator_code = serializers.SerializerMethodField()
class Meta:
model = Client
fields = '__all__'
read_only_fields = ('date_created', 'date_modified', 'operator_code', 'time_zone',)
def validate(self, attrs):
phone_number_exists = Client.objects.filter(phone=attrs['phone']).exists()
if phone_number_exists:
raise serializers.ValidationError(detail="phone number exists")
if attrs['phone'][0] != '7':
raise serializers.ValidationError(detail="phone number must start with 7")
if len(attrs['phone']) != 11:
raise serializers.ValidationError(detail="phone number must be 11 digits")
return super().validate(attrs)
def get_operator_code(self, obj):
return obj.operator_code
def get_time_zone(self, obj):
return obj.time_zone
class BroadcastSerializer(serializers.ModelSerializer):
end_date = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S')
class Meta:
model = Broadcast
fields = ['text', 'end_date',]
read_only_fields = ('date_created', 'date_modified', 'filter_client',)
views.py
class ClientViewSet(viewsets.ModelViewSet):
queryset = Client.objects.all()
serializer_class = ClientSerializer
def create(self, request):
serializer = ClientSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=201)
return Response(serializer.errors, status=400)
def update(self, request, pk=None):
client = get_object_or_404(Client, pk=pk)
serializer = ClientSerializer(client, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=400)
def destroy(self, request, pk=None):
client = get_object_or_404(Client, pk=pk)
client.delete()
return Response(status=204)
class BroadcastViewSet(viewsets.ModelViewSet):
queryset = Broadcast.objects.all()
serializer_class = BroadcastSerializer
filter_backends = [DjangoFilterBackend, SearchFilter]
def create(self, request):
serializer = BroadcastSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=201)
return Response(serializer.errors, status=400)
def update(self, request, pk=None):
broadcast = get_object_or_404(Broadcast, pk=pk)
serializer = BroadcastSerializer(broadcast, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=400)
def destroy(self, request, pk=None):
broadcast = get_object_or_404(Broadcast, pk=pk)
broadcast.delete()
return Response(status=204)