I used Django restframework and mongoengine.
Here is my model and serializer.
[model.py]
class Attachment(EmbeddedDocument):
attachment_id = SequenceField()
path = StringField()
path_small = StringField()
class Book(Document):
book_id = SequenceField()
user_id = LongField(required=True)
attachments = ListField(EmbeddedDocumentField(Attachment))
created_at = DateTimeField(default=datetime.now().replace(microsecond=0))
updated_at = DateTimeField(default=datetime.now().replace(microsecond=0))
[serializer.py]
from rest_framework_mongoengine.serializers import DocumentSerializer
from rest_framework.serializers import ImageField
from books.models.mongo import Book
class BookSerializer(DocumentSerializer):
image = ImageField()
class Meta:
model = Appeal
fields = (
'book_id',
'image',
)
Work flow like this.
Upload image to s3
Get s3 path
Save s3 path to attachments field in models.py.
So do not defined attachments to ImageField() in models.py.
Just set image = ImageField() in serializer to validate it is correct image.
But when I validate with serializer.is_valid(), image get None.
[views.py]
class BookList(GenericAPIView):
serializer_class = BookSerializer
queryset = ''
def post(self, request: Request) -> Union[Response, NoReturn]:
serializer = BookSerializer(data=request.data)
if serializer.is_valid():
print(serializer.data)
appeal = CreateAppealInteractor().execute(request=serializer.data)
return Response(status=status.HTTP_200_OK)
As you know that after serializer.is_valid(), I printed serializer.data.
But it throw None like this -> {'book_id': 1, 'image': None}
Is there any error in my code?
Thanks.
Problem is solved in chat room. Just use validated_data.
class BookList(GenericAPIView):
serializer_class = BookSerializer
queryset = ''
def post(self, request: Request) -> Union[Response, NoReturn]:
serializer = BookSerializer(data=request.data)
if serializer.is_valid():
appeal = CreateAppealInteractor().execute(request=serializer.validated_data)
return Response(status=status.HTTP_200_OK)
Related
I have simple viewset like this
in views.py
class MyFileViewSet(viewsets.ViewSet):
http_method_names = ['post','get','put']
def list(self, request):
queryset = MyFile.objects.all()
serializer = MyFileSerializer(queryset, many=True)
return Response(serializer.data)
models.py
from xml.dom.minidom import DOMImplementation
from django.db import models
class MyModel(models.Model):
name = models.CharField(verbose_name='NAME', max_length=30)
file = models.FileField(upload_to='file/%Y/%m/%d')
is_transfer_finish = models.BooleanField(default=False)
created_at = models.DateTimeField(verbose_name='created', auto_now_add=True)
Now I can see the list of MyModel.
However I want to set post and push for this model,
I set
http_method_names = ['post','get','put']
But currently, there is only 'GET' on html.
I want to enable POST or PUT to create new entry.
Is it possible? how can I make this?
I have a post serializer and a postimage serializer to upload multiple images to a post. I have this serializer, but I am not sure how to make it in a way, so that I can upload multiple images, for example 5 images with a single post, like how we use with formsets coz now I can upload only 1 image in 'images' field.
These are the serializers. Please do have a look and let me know what changes I have to make...
Thanks
class PostImageSerializer(serializers.ModelSerializer):
class Meta:
model = PostImage
fields = ['id', 'images',]
class PostSerializer(TaggitSerializer, serializers.ModelSerializer):
user = serializers.ReadOnlyField(source='user.username')
post_date = serializers.ReadOnlyField()
postimage_set = PostImageSerializer(many=True)
likes = UserSerializer(many=True)
class Meta:
model = Post
fields = ['id','title', 'post_date', 'updated', 'user', 'image', 'postimage_set']
def create(self,validated_data):
user = self.context['request'].user
title = validated_data['title']
image = self.context['request'].FILES.get('image')
images = self.context['request'].FILES.get('images')
m1 = Post(user=user,title=title,image=image,)
m1.save()
m2 = PostImage(post=m1, images= images)
m2.save()
validated_data['images']=m2.images
validated_data['image']=m1.image
return validated_data
views
class CreatePostAPIView(generics.CreateAPIView):
serializer_class = PostCreateSerializer
permission_classes = [IsAuthenticated]
def create(self, request, *args, **kwargs):
serializer = PostCreateSerializer(data=request.data, context={'request':request,})
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
This solved the problem
def create(self, validated_date):
images = self.context['request'].FILES.getlist('images')
for image in list(images):
m2 = PostImage(post=m1, images= image)
m2.save()
This is how you do the multiple upload on drf: example below on create you can access the multiple item you posted:
e.g posted:
Formdata
images: File.jpeg
images: File2.jpeg
images: File3.jpeg
class TestSerializer(serializers.Serializer):
images = serializers.ListField(child=serializers.FileField())
class CreatePostAPIView(generics.CreateAPIView):
permission_classes = [AllowAny]
serializer_class = TestSerializer
def create(self, request, *args, **kwargs):
images = request.data['images']
I would do it like this.
Make a PostModel and a PostImageModel (with a post ForeignKey) for each post image. And then in the serializer, make relation field with both.
Something like this:
models.py
class Post(Model):
post details ...
class PostImage(Model):
post = models.ForeigKey(Post, ...)
image = models.ImageField(...)
serializers.py
class PostImageSerializer(serializers.ModelSerializer):
class Meta:
model = PostImage
fields = '__all__'
class PostSerializer(serialiers.ModelSerializer):
images = serializers.SlugRelatedField(slug_field='image', many=True, ...)
class Meta:
model = Post
fields = [..., 'images']
views.py
class CreatePostView(CreateView):
classForm = PostForm (with images field)
def form_valid(self, form):
new_post = form.save(commit=False)
for image in new_post.images:
new_image = PostImage(post=new_post, image=image)
new_image.save()
new_post.save()
return super()form_valid(form)
So then in your api you should be able to see the post model with the images attached to it.
I have almost tried everything but am not able to reach at the point
model.py file
class RecievingImages(models.Model):
"""Original and Masked Images"""
....
name = models.CharField(max_length = 100, unique = True, primary_key=True)
area = models.IntegerField()
number = models.IntegerField()
agency_name = models.CharField(max_length=100, default='general')
rawImage = models.ImageField(upload_to=imageNameForRawImage,)
...
class UpdationImages(models.Model):
""" Update Image wrt name"""
....
name = models.ForeignKey(RecievingImages, on_delete=models.PROTECT, related_name='updated')
updated_image = models.ImageField(upload_to=UpdatedImageFolder,)
updated_image_url = models.TextField(default='None')
....
serializer.py
class UpdatedImageSerializer(serializers.ModelSerializer):
class Meta:
model = UpdationImages
fields = ('name', 'updated_image', 'updated_image_url')
class RecievingImagesSerializer(serializers.ModelSerializer):
updated = UpdatedImageSerializer(many= True, read_only=True)
class Meta:
model = RecievingImages
fields = ('updated','name','area','number','agency_name', rawImage)
I have used related_name in the model and also following the documentation along with that with many = True
But still in serializer.data updated does not show
views.py
class MappingSinglePhoto(APIView):
""" Mapping Single Image """
def post(self, request):
try:
data = request.data
# import pdb; pdb.set_trace()
name_of_image = data['name']
mapped_images_qs = UpdationImages.objects.select_related('name').filter(name = name_of_image)
for image in mapped_images_qs:
serializer = RecievingImagesSerializer(instance = image)
pdb.set_trace()
serializer.data
# return Response(serializer.data)
except Exception as e:
print(e)
NOTE
if I use depth=1 then it's working fine, but I am not looking for all the fields that depth displays.
Thanks & Regards
Thanks to #ArakkalAbu
There was a problem in query views.py
class MappingSinglePhoto(APIView):
""" Mapping Single Image """
def post(self, request):
try:
data = request.data
# import pdb; pdb.set_trace()
name_of_image = data['name']
mapped_images_qs = RecievingImages.objects.filter(name = name_of_image)
for image in mapped_images_qs:
serializer = RecievingImagesSerializer(instance = image)
pdb.set_trace()
serializer.data
# return Response(serializer.data)
except Exception as e:
print(e)
i am trying to insert product in my database using django custom fields, but it's showing me error that Product matching query does not exist.
it would be great if anybody could figure me out where should i make changes in my code. thank you so much in advance.
views.py
class ProductAdd(APIView):
def post(self, request, format=None):
data = request.data
title = data['title']
slug = data['slug']
description = data['description']
# created_on = data['created_on']
# status = data['status']
queryset = Product.objects.filter(title__contains=title,slug__contains=slug,description__contains=description)
query_slug = Product.objects.get(slug__exact=slug).first()
try:
if query_slug == None:
# queryset.annotate(Count(title,slug,description,created_on,status))
queryset.annotate()
Response({"msg":"product added succesfully!"}, status=HTTP_201_CREATED)
else:
print("query already exist!")
except ValueError:
return Response(status=HTTP_400_BAD_REQUEST)
As the error said, it could not find a product based on given slug. To prevent this error from raising, you can use .filter instead of .get:
query_slug = Product.objects.filter(slug__exact=slug).first()
Also, I would recommend using a serializer to serialize and store data in DB. More information can be found in documentation. Here is an example:
# serializer
from rest_framework import serializers
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = "__all__"
def validate_slug(self, value):
if Product.objects.filter(slug=slug).exists():
raise serializers.ValidationError("Product Exists")
return value
# view
from rest_framework import generics
class ProductAdd(generics.CreateAPIView):
serializer_class = ProductSerializer
I want to write a viewset in Django Rest Framework which allow user upload a list of new Images with these Order number together. But I don't know what field to use in DRF.
My serializer:
class ContentSerializer(ModelSerializer):
fileUpload = FileField(max_length=100000, allow_empty_file=False, use_url=False)
order_num = IntegerField(required=False)
class Meta:
model = Article
fields = [
'fileUpload',
'order_num',
]
class ArticleSerializer(ModelSerializer):
file_uploads = ListField(child=ContentSerializer(),write_only=True)
class Meta:
model = Article
fields = [
'file_uploads',
]
My Viewset:
class FeedEditAPIView(ModelViewSet):
'''
Use Form Data to PATCH
'''
queryset = Article.objects.all()
serializer_class = ArticleSerializer
lookup_field = 'id'
def edit_article(self, request, id):
print request.POST.getlist('file_uploads') // This return [u'{"file":{},"order_num":0}']
When I print request POST file_uploads, it return [u'{"file":{},"order_num":0}']. But I want to return [u'{"file":<files_object>,"order_num":0}'] instead of
Use multipartparser, which supports file uploads and request.data
class FeedEditAPIView(ModelViewSet):
'''
Use Form Data to PATCH
'''
parser_classes = (MultiPartParser,)
queryset = Article.objects.all()
serializer_class = ArticleSerializer
lookup_field = 'id'