I have this text choices model
models.py
class PostType(models.TextChoices):
DECLARE = 'DECLARE'
UPDATE = 'UPDATE'
SUCCESS = 'SUCCESS'
class Post(models.Model):
# ulid does ordered uuid creation
uuid = models.UUIDField(primary_key=True, default=generate_ulid_as_uuid, editable=False)
created = models.DateTimeField('Created at', auto_now_add=True)
updated_at = models.DateTimeField('Last updated at', auto_now=True, blank=True, null=True)
creator = models.ForeignKey(
User, on_delete=models.CASCADE, related_name="post_creator")
join_goal = models.ForeignKey(JoinGoal, on_delete=models.CASCADE)
body = models.CharField(max_length=511, validators=[MinLengthValidator(5)])
hash_tags = models.ManyToManyField(HashTag)
type = models.CharField(
choices=PostType.choices,
max_length=50,
)
for some reason on the mobile front-end it's returning as:
React Native Code
console.log(response[0].type)
console.log(typeof(response[0].type))
Console
LOG ('UPDATE', 'Update')
LOG string
The above were produced by console.log
the response and console.log
typeof
on the key in the response as well. This tells me that Django is sending it as a tuple of ('<type all caps>', '<type camel case>')
and then React Native is converting it to a string and printing is as such. Why is this happening? What can I do on Django to ensure just 'Declare'
, 'UPDATE'
or 'SUCCESS'
is returned to the react native?
view.py
@api_view(['GET'])
def get_initial_posts(request, count):
serializer = full_post_data_serializer(Post.objects.order_by('-uuid')[:count])
return Response(serializer.data, status=status.HTTP_200_OK)
helper.py
def full_post_data_serializer(post_query_set: QuerySet):
query_set_annotated = post_query_set.annotate(
creator_username=F('creator__username'),
goal_description=F('join_goal__goal__description'),
goal_uuid=F('join_goal__goal__uuid'),
reply_count=Count('replypost', distinct=True),
cheer_count=Count('cheerpost', distinct=True)
)
return FullPostDataSerializer(query_set_annotated, many=True)
serializer.py
class FullPostDataSerializer(serializers.ModelSerializer):
goal_uuid = serializers.SlugField()
creator_username = serializers.SlugField()
reply_count = serializers.IntegerField()
cheer_count = serializers.IntegerField()
goal_description = serializers.SlugField()
class Meta:
model = Post
fields = (
'body', 'join_goal', 'created', 'creator_username', 'goal_description', 'reply_count', 'cheer_count',
'images', 'uuid', 'type', 'creator', 'videos', 'goal_uuid'
)
CodePudding user response:
You can find an answer here: https://stackoverflow.com/a/28954424/1935069
This is slightly dependent on which version of DRF and Django you are using. What I would do is to be explicit and modify the serializer to use a serializers.SerializerMethodField and get the display value for the choices field like so:
class FullPostDataSerializer(serializers.ModelSerializer):
... # your existing code goes here
type = serializers.SerializerMethodField()
def get_type(instance):
return instance.type.value
...
This should return the proper value in the serializer.
Another thing to note is that type
is a reserved keyword in python. You can use it like this, but really should not, so I suggest a rename of the variable if possible