0

For some reason at if serializer.is_valid(raise_exception=True) my code is complaining about the list hash_tags, which should be primary keys of the class HashTag that the keys in the list aren't valid, but as you can see I have a line under views.py, which is: hash_tags = [HashTag.objects.get_or_create(hash_tag=ht)[0].hash_tag for ht in hash_tags_list] that should be generate a valid list of primary keys. What is going on?

serializer.py

class Post(AbstractBaseModel):
    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,
    )

class HashTag(models.Model):
    hash_tag = models.CharField(max_length=140, primary_key=True, validators=[
        MinLengthValidator(1)])
    # No update added, because cannot be edited. Can only be added and deleted

Serializer.py

class PostSerializer(serializers.ModelSerializer):
    class Meta:
        model = Post
        fields = ('creator', 'join_goal', 'body', 'uuid', 'created', 'type', 'updated_at', 'hash_tags')

view.py

@api_view(['POST'])
def post_create_update_post(request):
    """
    POST endpoint for current user creating a goal update post
    """
    user_uuid = str(request.user.uuid)

    request.data['creator'] = user_uuid
    request.data['type'] = PostType.UPDATE
    post_text = request.data['body']
    hash_tags_list = extract_hashtags(post_text)
    hash_tags = [HashTag.objects.get_or_create(hash_tag=ht)[0].hash_tag for ht in hash_tags_list]
    request.data['hash_tags'] = hash_tags

    try:
        with transaction.atomic():
            serializer = PostSerializer(data=request.data)
            if serializer.is_valid(raise_exception=True):
                post_obj = serializer.save()
    except Exception as e:
        return Response(dict(error=str(e),
                             user_message=error_message_generic),
                        status=status.HTTP_400_BAD_REQUEST)

    return Response(serializer.data, status=status.HTTP_201_CREATED)

here is the full error that comes out of e at except Exception as e

ValidationError({'hash_tags': [ErrorDetail(string='Invalid pk "['Test']" - object does not exist.', code='does_not_exist')]})

the weird thing is if I do this in the console

HashTag.objects.get(pk='Test')
<HashTag: HashTag object (Test)>

we can clearly see there does exist a HashTag object with the pk='Test'. My theory is because I'm passing in a list of primary keys. Even though I assumed that should be fine for ManyToMany relation.

  • Please add the full error traceback to your question! – Klaus D. Oct 17 '21 at 23:26
  • @KlausD. added the full stack error –  Oct 17 '21 at 23:28
  • Your generic exception handling swallows your real traceback. You should temporarily switch that off for diagnosis. – Klaus D. Oct 17 '21 at 23:33
  • since I'm running it as a test even if I turn it off it returns as `400` with that same error –  Oct 17 '21 at 23:41
  • @KlausD. I don't think it's eating anything that seems to be the error –  Oct 17 '21 at 23:44
  • Solution: https://stackoverflow.com/questions/33182092/django-rest-framework-serializing-many-to-many-field –  Oct 17 '21 at 23:51

1 Answers1

0

If you read the error carefully you see that the data which you pass is "['Test']" so model is trying to find the hash_tag = "['Test']" which is not present in your database and thats why you are getting the above error.

Here is the to fix the issue :-

post_obj = serializer.save()
for ht in hash_tags_list:
    hash_tag = HashTag.objects.get_or_create(hash_tag=ht)
    post_obj.hash_tags.add(hash_tag)
Shreeyansh Jain
  • 1,407
  • 15
  • 25
  • I think the issue with this solution is if you notice I return a `serializer.data` doing it this way will not ensure that the data is returned in the response. –  Oct 18 '21 at 01:13