I am trying to post image in to page album , i used this /{album-id}/photos to post image in to particulate page album , but using this i can post into profile album . how i can post image into page album . i used this code for post:
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:image, #"source",nil ];
/* make the API call */
[FBRequestConnection startWithGraphPath:#"/607843282662042/photos"
parameters:params
HTTPMethod:#"POST"
completionHandler:^(
FBRequestConnection *connection,
id result,
NSError *error
)
{
/* handle the result */
NSLog(#" %#", result);
self.uploadingText.alpha = 0;
}];
Related
I am trying to update a User Profile by making a multipart/form-data put request (from my vue frontend using axios) containing a png blob image file. I receive an error message: File extension “” is not allowed.
This is the File Field on the Userprofile Model:
profile_picture = models.FileField(
_("Profile Pictures"),
upload_to="profile_picture",
max_length=100,
blank=True,
null=True,
)
These are the signals I use in the Userprofile model to save and update the Model.
#receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.create(user=instance)
#receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
instance.profile.save()
I think it may be because of these or something other specific to the Userprofile model that creates the error because on another model the file upload works as intended, although there I am making a post and not a put request. The Userprofile model is connected to the User by a One to One Field.
Ther is nothing special in my serializer or views that could be causing the bug.
I have no Idea what I could do to fix this. Thanks for all advice. If you need any other information feel free to ask.
The image is the formdata sent with the put request... maybe somethings wrong there:
The axios code that makes the request:
import axios from 'axios'
const apiClient = axios.create({
baseURL: `http://127.0.0.1:8000/`,
withCredentials: false,
headers: {
Accept: 'application/json',
'Content-Type': 'multipart/form-data'
}
})
export default {
updateUser(pk, params) {
return apiClient.put('/users/' + pk + '/', params)
}
}
This is the part where I crop a picture and it is a dataURI which I then convert to a blob to send to the backend server:
methods: {
crop() {
const { coordinates, canvas } = this.$refs.cropper.getResult()
this.coordinates = coordinates
this.file = canvas.toDataURL()
},
uploadImage(event) {
const input = event.target
if (input.files && input.files[0]) {
// create a new FileReader to read this image and convert to base64 format
const reader = new FileReader()
// Define a callback function to run, when FileReader finishes its job
reader.onload = (e) => {
// Read image as base64 and set to imageData
this.file = e.target.result
}
// Start the reader job - read file as a data url (base64 format)
reader.readAsDataURL(input.files[0])
}
},
dataURItoBlob(dataURI) {
// convert base64 to raw binary data held in a string
const byteString = atob(dataURI.split(',')[1])
// separate out the mime component
const mimeString = dataURI
.split(',')[0]
.split(':')[1]
.split(';')[0]
// write the bytes of the string to an ArrayBuffer
const ab = new ArrayBuffer(byteString.length)
const ia = new Uint8Array(ab)
for (let i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i)
}
return new Blob([ab], { type: mimeString })
},
async updateUser() {
this.crop()
delete this.user.password2
const formData = new FormData()
if (this.file)
formData.append('profile_picture', this.dataURItoBlob(this.file))
if (this.user.username) formData.append('username', this.user.username)
else formData.append('username', this.$auth.user.username)
if (this.user.email) formData.append('email', this.user.email)
if (this.user.bio) formData.append('bio', this.user.bio)
if (this.user.password) formData.append('password', this.user.password)
else formData.append('password', this.$auth.user.password)
await UserFormService.updateUser(this.$auth.user.pk, formData)
await this.$store.dispatch('users/updateUser', this.user)
this.$auth.setUser(this.$store.state.users.user)
this.$router.push('/users/me')
Since your endpoint requires a specific file name extension you will have to set it manually because blobs do not have file names and the default used for a file upload is blob. There is a third optional parameter in FormData.append to set a file name
formData.append('profile_picture', this.dataURItoBlob(this.file), 'some_filename.valid_extension')
I have an HTML (annotator.html) page where the top half contains a table. I have JavaScript code that pulls data out of the data model when the user selects a row in the table and displays that data in a div below the table.
My Javascript looks like this:
$('#radiological tbody').on( 'click', 'tr', function () {
if ( $(this).hasClass('selected') ) {
$(this).removeClass('selected');
}
else {
//first unselect any other selected row
dt_table.$('tr.selected').removeClass('selected');
//then select row of interest
$(this).addClass('selected');
var rowIndex = dt_table.row('.selected')[0];
var row = dt_table.rows(rowIndex);
var id = row.data()[0]['id'];
var url = '/report/' + id + '/';
//window.location = url;
$.ajax({
url: url,
type: 'get', // This is the default though, you don't actually need to always mention it
success: function(data) {
},
failure: function(data) {
alert('Got an error dude');
}
});
And correctly populates the bottom half of my page but also updates the top half. I Just want the bottom half refreshed.
My report view looks like this:
def report_page(request, id):
template_name = "annotator.html"
data = Radiology2.objects.get(id=id)
context = {"data": data}
context["title"] = title
context["version"] = version
context["id"] = id
if (request.is_ajax()):
# return render(request, template_name, context)
return JsonResponse(context)
else:
return render(request, template_name, context)
I added support for AJAX. I'm just not sure how to return from view properly when AJAX is used. Obviously, I'm not understanding something.
Instead of Ajax, I replaced window.location=url; with $('#divIdToRefresh').load(url + ' #divIdToRefresh');
You can easily use Ajax - jQuery or native JS would be better for that
I am trying to save data into a model using django-rest framework. I have already written the api, it works fine when i access it directly using the url to api. But I get a bad-request error when i try to post data using ajax.
If it is working fine when data is inserted using the api interface, it should work fine when data is inserted using ajax....but instead i am getting a bad request.
here is the AJAX request method(Jquery):
$("form").submit(function(event){
event.preventDefault();
var this_ = $(this);
var formData =this_.serialize();
$.ajax({
url: "/api/forum/posts/{{ post_question.thread_id.id }}/create",
data: formData,
method: "POST",
success: function (data) {
console.log("successfully returned");
console.log(data);
displayPosts();
},
})
Serializers are as follow, in api/serializers.py :
class ThreadModelSerializer(serializers.ModelSerializer):
created_by = UserDisplaySerializer(read_only=True)
class Meta:
model = Thread
fields = '__all__'
class PostModelSerializer(serializers.ModelSerializer):
posted_by = UserDisplaySerializer(read_only=True)
class Meta:
model = Post
fields = '__all__'
Models for the Post and Thread are as follow in models.py:
class Thread(models.Model):
thread_subject = models.CharField(max_length=250)
posted_on = models.DateTimeField(auto_now=True)
category = models.CharField(max_length=250)
forum_id = models.ForeignKey(Forum, on_delete=models.CASCADE)
created_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
class Post(models.Model):
post_message = models.TextField()
thread_id = models.ForeignKey(Thread, on_delete=models.CASCADE)
parent_id = models.ForeignKey('self', on_delete=models.CASCADE, null=True, blank=True)
posted_on = models.DateTimeField(auto_now=True)
posted_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
and finally the API view is like this, in api/views.py:
class PostCreateApiView(generics.CreateAPIView):
serializer_class = PostModelSerializer
permission_classes = [permissions.IsAuthenticated]
def perform_create(self, serializer, *args, **kwargs):
thread_id = self.kwargs.get('thread_id', None)
thread = get_object_or_404(Thread, id=thread_id)
parent_post = get_object_or_404(Post, thread_id=thread_id, parent_id__isnull=True)
serializer.save(posted_by=self.request.user, parent_id=parent_post, thread_id=thread)
and url route is as follow in api/urls.py :
path('posts/<int:thread_id>/create', PostCreateApiView.as_view(), name='post_create'),
Hopefully I am able to make the problem statement clear, need help.
When I create a new post using the api url directly, example :
http://localhost:8000/api/forum/posts/4/create
I get no errors and post is successfully inserted in the database.
But when I try to insert the data using the template(ajax), example :
http://localhost:8000/forums/thread/4/
I get a bad request like following :
Bad Request: /api/forum/posts/4/create
HTTP POST /api/forum/posts/4/create 400 [0.02, 127.0.0.1:40630]
Need help, I have tried hard, but can't find the solution.
Awaiting reply. Thanks.
I had the exact same problem as you: Just a 400 Error with no further information.
Although i dont know what your Problem is exactly i can tell you that adding an error function to your ajax request will help you debug it.
The reason is that you are not actually causing a python error, you are just making a request that Django Rest Framework thinks is wrong. It will tell you what is wrong in the response which is returned under a 400 status code and thus not shown in the ajax success function but in the error function.
$("form").submit(function(event){
event.preventDefault();
var this_ = $(this);
var formData =this_.serialize();
$.ajax({
url: "/api/forum/posts/{{ post_question.thread_id.id }}/create",
data: formData,
method: "POST",
success: function (data) {
console.log("successfully returned");
console.log(data);
displayPosts();
},
error: function (jqXhr, textStatus, errorThrown) {
console.log('ERROR')
console.log(jqXhr)
},
})
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
I have written the following code to print model data in view,
but it displays an empty view page. This is the controller code:
function new1()
{
$user = JFactory::getUser();
//assign the model
$model = $this->getModel('add');
$connect= $model->addJob(JRequest::get());
$view = $this->getView('helloworld', 'html');
$view->setLayout('new');
$view->setModel($model,false);
$view->display();
}