Can't Get Image from Django Api To React Native - django

Hello Friends I Can't Get Image From Django To React Native
Here My Code
Fetch APi
const [add, setStudents] = useState([{}])
async function getAllStudent() {
try {
const add = await axios.get('http://192.168.1.77:19000/api/add/')
method:'GET',
setStudents(add.data)
}
catch (error) {
console.log(error)
}
}
getAllStudent();
FlatList :
<FlatList
data={add}
renderItem={({item})=>
<Image
style={{width:200,height:200, backgroundColor:'green',}}
source={{uri:item.image}}
/>
}
/>
Django Code Is Here
Views
class addpost(viewsets.ViewSet):
def list(self,request):
postadd1 = postadd.objects.all()
postaddserial1 = postaddserial(postadd1,many=True)
return Response(postaddserial1.data)
def create(self,request):
postaddserial1 = postaddserial(data=request.data)
if postaddserial1.is_valid():
postaddserial1.save()
return Response(postaddserial1.data, status=status.HTTP_201_CREATED)
return Response(postaddserial1.errors, status=status.HTTP_400_BAD_REQUEST )
def retrieve(self,request,pk=None):
queryset = postadd.objects.all()
contact = get_object_or_404(queryset,pk=pk)
postaddserial1 = postaddserial(contact)
return Response(postaddserial1.data)
def update(self,request,pk=None):
contact = postadd.objects.get(pk=pk)
postaddserial1 = postaddserial(contact,data=request.data)
if postaddserial1.is_valid():
postaddserial1.save()
return Response(postaddserial1.data,status=status.HTTP_201_CREATED)
return Response(postaddserial1.errors,status=status.HTTP_400_BAD_REQUEST)
def destroy(self, request, pk=None):
postadd1 = postadd.objects.get(pk=pk)
postadd1.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
Serializer
class postaddserial(serializers.ModelSerializer):
class Meta:
model = postadd
fields ='__all__'
Model
class postadd(models.Model):
city=models.CharField(max_length=122)
carinfo=models.CharField(max_length=122)
milage=models.CharField(max_length=122)
price=models.CharField(max_length=122)
company=models.CharField(max_length=122)
image = models.ImageField(upload_to ='static/Images', height_field=None, width_field=None, max_length=100,)
engine=models.CharField(max_length=122)
contact=models.CharField(max_length=122)
I make django Api to add product in react native. i show image from post man . but cant get image in react native from api
i am making application where i can add product from django rest framework and show it on react native through api i get all data in react native but cant get image from api. when i use postman i get image from api but when i use api on react native i can't get image

You need to define media settings and absolute url for image or files.
For more helo you can see here
Django serializer Imagefield to get full URL

Related

Sending Django requests to NextJS with data

I am looking at integrating NextJS into an existing Django project. The project makes heavy use Django templates for most of its pages and I am looking at modernising the project by taking advantage of React and building out a design / component system. The idea is that we would look at replacing Django with NextJS eventually.
I have been able to use Django to proxy a request through to NextJS, and it works great! I have also been able to send data directly to the NextJS route so that I do not have to call back to Django to get data. This approach annoyingly has the limitation of only sending key/value data.
Here is the working code.
# django
def get(self, request, *args, **kwargs):
data = request.GET
return self._handle_request(data, requests.post)
def _handle_request(self, data, make_request):
data = {"hello": "world"}
response = make_request("http://localhost:3000", data=data)
return HttpResponse(response)
//nextjs
import parse from "urlencoded-body-parser";
export async function getServerSideProps(context) {
const { req } = context;
const props = await parse(req);
return { props };
};
So with this in mind, is there a better way to achieve sending data to a NextJS route without having to do a callback?
After some research I was able to achieve this by using application/json content type.
class NextJsView(WhiteLabelMixin, View):
def get(self, request, *args, **kwargs):
data = request.GET
return self._handle_request(data, requests.post)
def _handle_request(self, data, make_request):
data = {"hello": {"dark": "world"}}
response = make_request("http://localhost:3000", json=json.dumps(data))
return HttpResponse(response)
import getRawBody from "raw-body";
export async function getServerSideProps(context) {
const { req } = context;
let props = {};
if (req.method == "POST") {
const body = await getRawBody(req);
props = JSON.parse(JSON.parse(body));
}
return { props };
}

File : "Upload a valid image" using Postman in Django Rest Framework

I am using Django Rest Framework to upload profile picture and Google Cloud Storage to store my images. I test my API with Postman and i have this result :
Postman result
And here is my Postman headers : Postman headers
This is my code :
class ProfilePictureSerializer(serializers.Serializer):
file = serializers.ImageField()
class UploadProfilePictureAPI(APIView):
permission_classes = (IsAuthenticated,)
parser_classes = [FileUploadParser]
#staticmethod
def post(request):
input_serializer = serializers.ProfilePictureSerializer(
data=request.data
)
input_serializer.is_valid(raise_exception=True)
profile = ProfileService.upload_profile_picture(
request.user,
**input_serializer.validated_data
)
output_serializer = serializers.ProfileSerializer(profile)
return Response(
output_serializer.data,
status=status.HTTP_202_ACCEPTED
)
#staticmethod
def upload_profile_picture(user, file):
user.profile.profile_picture = file
user.profile.save()
return user.profile
path(
'upload/picture',
views.UploadProfilePictureAPI.as_view(),
name='api_upload_profile_picture'
),
I does not understand why I have this response. Could you help me ?
I think the issue here might be that FileUploadParser expects you to just send raw binary data (you can see the binary option in Postman).
In your current example, can you just try to send the binary data like so?
For multipart form you should use the MultiPartParser: https://www.django-rest-framework.org/api-guide/parsers/#multipartparser

Add route to view in flask-admin

so basically I'm trying to add a custom endpoint to my Flask + Flask-Admin app that allows admins to download a CSV.
Something like this:
class MyAdminIndexView(AdminIndexView):
#expose('/')
def index(self):
return self.render('admin/home.html')
def is_accessible(self):
return current_user.has_role('admin')
#expose('/csv-export')
def csv_export(self):
batch_num = request.args.get('batch_num')
if not batch_num:
flash('Invalid batch id', 'danger')
abort(404)
si = io.StringIO()
cw = csv.writer(si)
rows = MyObj.query.filter_by(batch_num=batch_num).all()
cw.writerows(rows)
output = make_response(si.getvalue())
output.headers["Content-Disposition"] = "attachment; filename=export.csv"
output.headers["Content-type"] = "text/csv"
return output
But if I add this to my base admin view, the '/csv-export' route doesn't register and I get a 404.
I guess I could add an entirely new Blueprint just for this endpoint but it seems like a lot of work for a simple endpoint that doesn't require a separate template view. Any tips?

ionic 2 upload image to django rest

I am trying to upload an image from Ionic 2 app to Django-powered website through Django Rest API.
The API is working and tested through Postman but I always get HTTP 400 BAD Request error in Ionic.
Here is my code in Ionic:
openCamera(){
var options = {
sourceType: Camera.PictureSourceType.CAMERA,
destinationType: Camera.DestinationType.DATA_URL
};
Camera.getPicture(options).then((imageData) => {
this.imageName = imageData;
this.imageURL = 'data:image/jpeg;base64,' + imageData;
}, (err) => {
this.showAlert(err);
});
}
Upload file (I am serving my Django project on my local PC with IP address 192.168.22.4):
transferData(auth){
let headers = new Headers();
headers.append('Authorization', auth);
let formData = new FormData();
formData.append('image', this.imageURL, this.imageName);
this.http.post("http://192.168.22.4/api-imageUpload", formData, {headers: headers}).subscribe(res => {
let status = res['status'];
if(status == 200){
this.showAlert( "The image was successfully uploaded!");
}else{
this.showAlert("upload error");
}
}, (err) => {
var message = "Error in uploading file " + err
this.showAlert(message);
});
}
On Django, here is my serializer:
class ImageDetailsSerializer(serializers.ModelSerializer):
image = serializers.ImageField(max_length=None, use_url=True)
class Meta:
model = ImageDetails
fields= ('image','status','category', 'user') ####status, category has default value
and views.py:
class ImageDetailsViewSet(generics.ListCreateAPIView):
queryset = ImageDetails.objects.all()
serializer_class = ImageDetailsSerializer
I am not sure if my code in uploading file is correct. I am trying to pass the data through Form data since the form works well in my API. Is this method correct? Are there any other methods to get this work?
Note: I have tried to use Transfer Cordova plugin but it is not working.
I finally solved the problem. The HTTP 400 indicates that there is a syntax error somewhere in the code and that is the encoding used in the uploaded photo. Mobile data uses base64 encoding. When sending requests, the file will then be converted to a Unicode string.
On the other hand, Django-Rest uses normal encoding for images, thus by default, it cannot support base64 image. But luckily, this plugin is already available at GitHub.
You just need to install the plugin and import it on your serializers.py:
from drf_extra_fields.fields import Base64ImageField
class ImageDetailsSerializer(serializers.ModelSerializer):
image = Base64ImageField()
class Meta:
model = ImageDetails
fields= ('image','status','category', 'user')
On Ionic side, you have to submit the actual image not the imageURL. In my case I just have to tweak my code to:
transferData(auth){
let headers = new Headers();
headers.append('Authorization', auth);
let formData = new FormData();
formData.append('category', 1);
formData.append('status', 'Y')
formData.append('image', this.imageName);
this.http.post("http://192.168.22.4/api-imageUpload", formData, {headers: headers}).subscribe(res => {
let status = res['status'];
if(status == 201){
var message = "The image was successfully uploaded!";
this.showAlert(message);
}else{
var message = "upload error";
this.showAlert(message);
}
}, (err) => {
var message = "Error in uploading file " + err;
this.showAlert(message);
});
In order to inspect what's ongoing with the request:
from rest_framework.exceptions import ValidationError
class ImageDetailsViewSet(generics.ListCreateAPIView):
queryset = ImageDetails.objects.all()
serializer_class = ImageDetailsSerializer
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
if not serializer.is_valid():
print(serializer.errors) # or better use logging if it's configured
raise ValidationError(serialize.errors)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
Even without Base64 it is possible using ionic native components for file-transfer and image-picker see here: https://gist.github.com/AndreasDickow/9d5fcd2c608b4726d16dda37cc880a7b

Using nested objects with Django Rest Framework and unit tests

I wrote several unit tests on my Django Rest Framework endpoints without any trouble, until I tried to pass nested object in a POST request:
class BookTestCase(APIVersion, APITestCase):
def setUp(self):
self.url = self.reverse_with_get_params('book')
self.user = CustomerFactory.create().user
self.base_data = {"foo": "bar",
"credit_card": {"card_number": "1234567812345678",
"expiration_date": "1116",
"security_code": "359"},
"foo2": "bar2"}
def test_book(self):
add_token_to_user(self.user, self.client)
response = self.client.post(self.url, self.base_data)
self.assertEqual(response.status_code, 200)
Then, runing the related web service with a pdb.set_trace() at the very beginning, here is the content of request.DATA:
<QueryDict: {u'foo': [u'bar'],
u'credit_card': [u'expiration_date', u'security_code', u'card_number'],
u'foo2': [u'bar2']}>
As you can see, every level1 object is correctly filled, but credit card content has disapeared.
Any idea? Thanks!
Note: Django 1.6 / Rest Framework 2
You have to change to format of your post call. Try format='json'
response = self.client.post(self.url, self.base_data, format='json')