I thought I’d ask this here as I’m not too sure where I am going wrong. I am trying to do a POST request via AJAX using Django Rest Framework Class. However, I am getting the following error whenever the event fires:
OST http://127.0.0.1:8000/api/uservenue/ 400 (Bad Request)
This is what is appearing in the Stack Trace:
{"list":["This field is required."],"venue":["This field is required."]}
Context
I am trying to make it so when a user clicks an "add-to-list" button it sends a cafeName (and eventually other details) to a user defined list.
I’m wondering if someone could take a look at my code and give me some guidance as to where I am going wrong?
The Code
Here is the relevant model:
class UserVenue(models.Model):
venue = models.ForeignKey(mapCafes, on_delete=models.PROTECT)
list = models.ForeignKey(UserList, on_delete=models.PROTECT)
Here is the relevant serializer.py
class UserVenueSerializer(serializers.ModelSerializer):
class Meta:
model = UserVenue
fields = ['list', 'venue']
Here is the relevant URLs
router = DefaultRouter() #need help understanding router register
router.register('userlist', views.UserList)
router.register('uservenue', views.UserVenue)
Here is the relevant views.py
class UserVenue(viewsets.ModelViewSet):
serializer_class = UserVenueSerializer
queryset = UserVenue.objects.all()
@ensure_csrf_cookie
def get_queryset(self):
cafeName = self.request.GET.get('cafeName', None)
print(cafeName)
return UserVenue.objects.all()
And, finally, here is the ajax call with the CSRF code incl.
var csrftoken = jQuery("[name=csrfmiddlewaretoken]").val();
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function (xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
$.ajax({
type: "POST",
url : '/api/uservenue/',
//dataType: "json", //I tried using this and commenting it out and it made no diff.
//contentType: "application/json", //I tried using this and commenting it out and it made no diff.
data: {
'cafeName': cafeName,
'list_id': 1,
'csrfmiddlewaretoken': document.querySelector('input[name="csrfmiddlewaretoken"]').value,
},
success: function(data){
//$("user-list").html(data);
console.log('User clicked: ' + data)
},
failure: function(errMsg) {
alert(errMsg);
}
});
I’m not sure if this is an error in the Ajax or perhaps in my Views?
Thanks!
2
Answers
Turns out I was shadowing a variable. I had both imported UserVenue and was trying to name the class UserVenue this was causing the overall problem.
Renamed to views.py class to UserVenueViewset fixed it.
Let’s start with a simple pattern, we can go in depth where needed:
First in your js file you’ll need to do something like this:
Then, in your views.py you can do something like this:
Of course, don’t forget to route the views function to the ‘add_to_list’ url in your urls.py