I use Tastypie for Django's API. but it returns error.
my code is bellow.
$.ajax({
type : "POST",
url : "http://192.168.1.130:8000/api/user/author/",
data : '{"first_name": "111","second_name": "222"}',
success: function(){
alert('Submit Success')
},
dataType : 'json',
contentType : 'application/json',
processData: false
});
my api.py like this:
class AuthorResource(ModelResource):
class Meta:
queryset = Author.objects.all()
resource_name ='author'
fields = ['first_name','last_name']
filtering = {
'first_name': ALL,
}
authentication = Authentication()
authorization = Authorization()
it returns 200 and post nothing.How can I reslove it?
This is a dupe of Returning data on POST in django-tastypie.
Add always_return_data = True to your Resource meta
If object created successfully, the object uri will be shown in Location field in response headers.
Shouldnt the url be http://192.168.1.130:8000/api/author/ instead of http://192.168.1.130:8000/api/user/author/
Related
I want to send an array of values via AJAX to a Django view but I only find how to send forms.
For example I send the following array of values. How do I access that array in my views?
Let to_save = []
$.each($('.linea_producto').find('.esta_coleccion.elegido'), function(index, value) {
producto = $(this).find('.producto').text();
marca = $(this).find('.marca').text();
packaging = $(this).find('.packaging').text();
categoria = $(this).find('.categoria ').text();
to_save.push({marca, producto, packaging, category});
});
$.ajax({
url:'/target_url/',
type:'POST',
dataType: 'json',
contentType: 'application/json',
data: JSON.stringify(to_save),
success:function(response){
},
error:function(){
},
});
Thanks in advance!
You can access the data you have sent in the body of your POST request via request.POST like so:
def my_view(request):
post_data = request.POST
# do something with post_data
request.POST will be a dictionary-like object.
I'm pretty new to web development so please forgive me in advance for my ignorance.
I'm using React to try to post data to server endpoint managed by Django using this method:
sendData(data) {
const url = "http://127.0.0.1:8080/api/filtros/1/";
const requestOptions = {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify(data)
};
fetch(url, requestOptions);
}
On the onClick of a NavDropdown React component:
<NavDropdown.Item
key={item.id}
onClick={() =>
this.sendData({
id: 0,
dimension_id: dimension.id,
item_id: item.id,
usuario_id: 1
})
}
>
{item.descripcion}
</NavDropdown.Item>
This is how I register the url on the router using Django:
router.register('api/filtros/1', FiltroUsuariosViewSet, 'filtro')
My Django ModelViewSet looks like this:
class FiltroUsuariosViewSet(viewsets.ModelViewSet):
queryset = FiltroUsuarios.objects.all()
permission_classes = [
permissions.AllowAny
]
serializer_class = FiltroUsuariosSerializers
And my Django Serializer looks like this:
class FiltroUsuariosSerializers (serializers.ModelSerializer):
class Meta:
model = FiltroUsuarios
fields = ('id', 'dimension_id', 'item_id', 'usuario_id')
def create(self, validated_data):
post = FiltroUsuarios.objects.create(**validated_data)
When I click on the Component I get this:
POST http://127.0.0.1:8080/api/filtros/1/ 400 (Bad Request)
and apparently the error is on the fetch request.
Do you guys have any idea on whats the problem?
Thanks a lot in advance!
The best way to understand and get rid of 400 Bad Request errors when wiring Django and React, is to run Django in development mode and then fire up your browser's Network tab while sending the request.
Switch into the Network -> Response tab and call sendData(). Since you are running on Django's development server, you will get the specific exception on your 400 Bad Request error. To simulate this, see the screenshot below and notice:
{"user": ["Incorrect type. Expected pk value, received str."]}
Back to your problem, you have the following in your .sendData():
x = {
id: 0,
dimension_id: dimension.id,
item_id: item.id,
usuario_id: 1
}
Which you then call JSON.stringify() on. If dimension.id and item_id are both integer (a reasonable assumption), then you're passing the following as a payload:
JSON.stringify(x)
# returns:
"{"id":0,"dimension_id":1,"item_id":2,"usuario_id":3}"
Your Django Model for FiltroUsuarios defined these columns / fields, so you now need to check both your models and FiltroUsuariosSerializers that these are expected value / value types mapping to these columns.
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)
},
})
Have been trying to filter data using django-filters. The code is working when I send a separate POST or GET request from the template. I want to avoid that extra reload that's taking place to filter the table of information.
Here's the view:
def search(request):
dynamic_filter = [f.name for f in Controlpanel._meta.get_fields()]
class UserFilter(django_filters.FilterSet):
class Meta:
model = Controlpanel
fields = dynamic_filter
user_list = Controlpanel.objects.all()
user_filter = UserFilter(request.GET.get("filters[]"),
queryset=user_list)
chart = list(user_filter.qs.values())
return JsonResponse(chart, safe=False)
Here's the AJAX code that calls this above view:
$('#filter-data').on('submit', function (event) {
event.preventDefault();
var dynamic = $('#filter-data').serialize();
console.log($('#filter-data').serializeArray())
$.ajax({
url: '/search/',
type: 'GET',
data: {
filters : dynamic
},
dataType: 'json',
success : function(json) {
console.log(json); // log the returned json to the console
console.log("success"); // another sanity check
},
// handle a non-successful response
error : function(xhr,errmsg,err) {
console.log(xhr.status + ": " + xhr.responseText); // provide a bit more info about the error to the console
}
});
The request.GET(or POST) currently stays empty even if I add a CSRF token and make it a POST request.
I came across some question on SO stating that use of request.body solves the issue but even that was a fail.
The issue was that the POST request was being passed as a string.
This solved the issue:
user_filters = request.POST.get('filters', '')
user_filters = user_filters.split("&")
user_filters = {item.split("=")[0]: item.split("=")[1].replace("%20", " ")
for item in user_filters}
user_filters.pop('csrfmiddlewaretoken')
I have a Django - tastypie Resource as follows. It has multiple fields that has Many to Many Relations.
I am trying to get the fields "workflow_initiators", "workflow_submitters" and "workflow_approvers" and add the user to a respective group namely initiators, submitters and approvers.
My JSON Request as follows :
{
"workflow_approvers": [
"/client/api/v1/user/44/",
"/client/api/v1/user/6/"
],
"workflow_dept": [
"/client/api/v1/departments/1/",
"/client/api/v1/departments/2/"
],
"workflow_initators": [
"/client/api/v1/user/44/",
"/client/api/v1/user/6/"
],
"workflow_name": "Hello Workflow",
"workflow_submitters": [
"/client/api/v1/user/43/",
"/client/api/v1/user/6/"
],
}
I want to get the primary key from resource uri of tastypie in a hydrate() or a obj_create() method. In order to get the pk i used a function get_pk_from_uri(). But it throws an error of the following
error : global name 'get_pk_from_uri' is not defined
My Resource as follows :
class WorkflowResource(ModelResource):
workflow_dept = fields.ToManyField(DepartmentsResource, 'workflow_dept', related_name='departments', full=True)
workflow_initators = fields.ToManyField(UserResource, 'workflow_initators', related_name='user')
workflow_submitters = fields.ToManyField(UserResource, 'workflow_submitters', related_name='user')
workflow_approvers = fields.ToManyField(UserResource, 'workflow_approvers', related_name='user')
def obj_create(self, bundle, **kwargs):
submitters = bundle.data.get('workflow_submitters', [])
for submitter in submitters:
print(get_pk_from_uri(submitter)) # Throws Error
#Adding User to Group Logic
# g = Group.objects.get(name='submitters')
# g.user_set.add(your_user)
class Meta:
queryset = WorkflowIndex.objects.filter(is_active=True)
resource_name = 'workflows'
list_allowed_methods = ['get', 'post']
detail_allowed_methods = ['get', 'post', 'put', 'delete', 'patch']
serializer = Serializer()
default_format = 'application/json'
authentication = Authentication()
authorization = DjangoAuthorization()
always_return_data = True
Is there any other method to get the primary key and other fields from resource uri ? I did see get_via_uri() method but was unsure on how to implement the same.
Kindly guide me in resolving this issue.
References :
Stackoverflow - Get model object from tastypie uri
Tastypie Documents - get_via_uri()
You should go back to this post: Get model object from tastypie uri?
The get_pk_from_uri(uri) method that you can see in this answer is not part of the source code of Tastypie, as you can check here.
I suppose the guy wrote it by himself, and you should do the same sothat you won't get the error : global name 'get_pk_from_uri' is not defined error. I didn't tested his method thought.
Solution
David was correct. The get_pk_from_uri() is not an in built tasty-pie method, which i was mistaken.
P.S : I'm just making the answer clear so that someone find it useful.
When needed to extract the resource name or pk from the resource uri of tastypie. we will be able to access them from **kwargs of the below section. The Kwargs contains the follows
kwargs
{u'api_name': 'v1', u'pk': '1', u'resource_name': 'workflows'}
Add the following code to your resources.py or utils.py and include it in your API's to a get this method get_pk_from_uri
from django.core.urlresolvers import resolve, get_script_prefix
def get_pk_from_uri(uri):
prefix = get_script_prefix()
chomped_uri = uri
if prefix and chomped_uri.startswith(prefix):
chomped_uri = chomped_uri[len(prefix) - 1:]
try:
view, args, kwargs = resolve(chomped_uri)
except Resolver404:
raise NotFound("The URL provided '%s' was not a link to a valid resource." % uri)
return kwargs['pk']