1

I am learning how to use djangorestframework by building a microblog and I want users to be able to upload multiple (kind of like how twitter works). I got a particular error(check below) after using a particular approach(check code).

I have attached my models.py, serializers.py and views.py file:

MODELS.PY FILE:
class TweetFile(models.Model):
    tweep =  models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    file = models.FileField(upload_to='images')

class Tweets(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    texts = models.TextField()
    file_content = models.ManyToManyField(TweetFile, related_name='file_content')
    date_posted = models.DateTimeField(auto_now_add=True)
    tweep = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    likes = models.PositiveIntegerField(default=0)
    liker = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='user_like')
    # link = models.URLField()

    class Meta:
        # verbose_name = _('my thing')
        verbose_name_plural = _('Tweets')

    def __str__(self):
        return f"{self.texts}"



SERIALIZERS.PY FILE:
class TweetSerializer(serializers.ModelSerializer):
    tweep = serializers.SerializerMethodField('get_tweep_username')
    likes = serializers.SerializerMethodField('get_tweet_likes')
    liker = serializers.StringRelatedField(many=True)

    class Meta:
        model = Tweets
        fields = ['id','texts', 'file_content', 'date_posted', 'tweep', 'likes', 'liker']
        extra_kwargs = {
            "file_content": {
                "required": False,
            }
        }


VIEWS.PY FILE: 
@api_view(['POST'])
@permission_classes([IsAuthenticated])
def create_tweet(request):
    user = request.user
    if request.method == 'POST':
        serializer = TweetSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save(tweep=user)
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    else:
        return Response(serializer.errors, status=status.HTTP_405_METHOD_NOT_ALLOWED)

This particular approach gave me this error in my postman:

{ "file_content": [ "Incorrect type. Expected pk value, received InMemoryUploadedFile." ] }.

Could anybody tell me what I am doing wrong? or what I need to do? any help will be appreciated, thanks.

1 Answer 1

1

Okay, so I found a solution to this issue....and this is the code, hopefully someone finds it helpful:

models.py file

 class TweetFile(models.Model):
 tweep =  models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
 media = models.FileField(upload_to='images')

 def __str__(self):
     return f"{self.tweep.username}'s media images"


class Tweets(models.Model):
 id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
 texts = models.TextField()
 file_content = models.ManyToManyField(TweetFile, related_name='file_content', blank=True, null=True)
 date_posted = models.DateTimeField(auto_now_add=True)
 tweep = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)

 class Meta:

     verbose_name_plural = _('Tweets')

 def __str__(self):
     return f"{self.texts}"

Serializer.py file

 from rest_framework import serializers
from tweets.models import Tweets, TweetFile, Comments


class TweetSerializer(serializers.ModelSerializer):
 tweep = serializers.SerializerMethodField('get_tweep_username')
 
 class Meta:
     model = Tweets
     fields = ['id','texts', 'file_content', 'date_posted', 'tweep']
     extra_kwargs = {
         "file_content": {
             "required": False,
         }
     }
     

  # function that returns the owner of a tweet
 def get_tweep_username(self, tweets):
     tweep = tweets.tweep.username
     return tweep

Views.py file

@api_view(['POST'])
@permission_classes([IsAuthenticated])
@parser_classes([MultiPartParser, FormParser])
def create_tweet(request):
 user = request.user
 if request.method == 'POST':
     files = request.FILES.getlist('file_content')
     if files:
         request.data.pop('file_content')
         serializer = TweetSerializer(data=request.data)
         if serializer.is_valid():
             serializer.save(tweep=user)
             tweet_qs = Tweets.objects.get(id=serializer.data['id'])
             uploaded_files = []
             for file in files:
                 content = TweetFile.objects.create(tweep=user, media=file)
                 uploaded_files.append(content)
             
             tweet_qs.file_content.add(*uploaded_files)
             context = serializer.data
             context["file_content"] = [file.id for file in uploaded_files]
             return Response(context, status=status.HTTP_201_CREATED)
         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
     else:
         serializer = TweetSerializer(data=request.data)
         if serializer.is_valid():
             serializer.save(tweep=user)
             context = serializer.data
             return Response(context, status=status.HTTP_201_CREATED)
         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
 else:
     return Response(serializer.errors, status=status.HTTP_405_METHOD_NOT_ALLOWED)



configure your urls.py files appropriately and test the endpoint on POSTMAN, everything should work fine.

Sign up to request clarification or add additional context in comments.

3 Comments

Hello @Babayega, thanks for you work, it helped me as well but I got error on this part. tweet_qs = Tweets.objects.get(id=serializer.data['id']) it only worked when i do get_object_or_404 what is the issue??
Hello @Django-Rocks, what is the error you got when you used Tweets.objects.get(id=serializer.data['id'])?
Hello @Babayega, I'm getting this error:TypeError: Image() got an unexpected keyword argument 'media'. Please help out

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.