django ajax POST 404 not found - javascript

Recently I learned ajax but now i am trying to implement in my fjango project but it is not working.
signup.js
$(document).ready(function(){
$(document).on('submit', '#signup', function(e){
e.preventDefault();
var email = $('input[name="email"]').val();
var name = $('input[name="name"]').val();
var password1 = $('input[name="password1"]').val();
var password2 = $('input[name="password2"]').val();
var url = '/signup'
var req = new XMLHttpRequest();
req.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
if(req.responseText == 'true' ){
alert('account created')
}
}
};
req.open("POST", url, true);
req.send();
})
});
urls.py
urlpatterns = [
path('',login_required(StockView.as_view(), login_url='login'), name='stock'),
path('login/', LoginView.as_view(), name='login'),
path('signup/', SignupView.as_view(), name='signup'),
path('logout',LogoutView.as_view(), name='logout'),
path('addproduct/', login_required(AddProduct.as_view(), login_url='login'), name='addproduct'),
path('update/<int:pk>', login_required(EditProduct.as_view(), login_url='login'), name='editproduct'),
path('delete/', login_required(DeleteProducts.as_view(), login_url='login'), name='deleteproducts'),
view.py
class SignupView(TemplateView):
template_name = 'stock/signup.html'
def get(self, request):
form = SignUpForm()
args = {'form': form}
return render(request, self.template_name, args)
def post(self, request):
form = SignUpForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
raw_password = form.cleaned_data.get('password1')
user = authenticate(username=username, password=raw_password)
login(request, user)
return redirect('home')
else:
args = {'form': form}
return render(request, self.template_name, args)
form.py
class SignUpForm(UserCreationForm):
username = forms.CharField(max_length=30,widget=forms.TextInput(attrs={'class':'form-control','name':'name'}))
email = forms.EmailField(widget=forms.EmailInput(attrs={'class':'form-control'}))
password1 = forms.CharField(widget=forms.PasswordInput(attrs={'class':'form-control'}),help_text='Password Should Match',label='Password')
password2 = forms.CharField(widget=forms.PasswordInput(attrs={'class':'form-control'}),label='Password Confirmation')
class Meta:
model = AppUser
fields = ('username', 'email', 'password1', 'password2' )
template.html
<form method="post" id="signup" >
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="btn btn-primary" >Signup</button>
</form>
</div>
<script src="{% static 'assets/signup.js' %}"></script>
CONSOLE ERROR:
signup.js:21 POST http://127.0.0.1:8000/signup 404 (Not Found)
(anonymous) # signup.js:21
dispatch # jquery-2.1.4.js:4435
elemData.handle # jquery-2.1.4.js:4121

Try to send csrf token as you're trying to send data using the POST method. Inspect the form and you get a hidden input tag of csrf_token, include that in you ajax.

Related

How to allow JSON access to the text within a textarea in HTML>

I am trying to create a button that allows users to save edits to a post, which they write in a textarea, through JSON. I am trying to save the data through a PUT request, but I get the following error:
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
javascript function:
function save_edit(id){
console.log("save button is clicked");
const edit_area = document.querySelector(`#edit_area_${id}`);
//save the post
fetch(`/edit/${id}`,{
method: 'PUT',
post: JSON.stringify({
post: edit_area.value
})
})
fetch(`/edit/${id}`)
.then(response => response.json())
.then(post => {
const post_itself =
document.querySelector(`#post_itself_${id}`);
post_itself.value = `${post.post}`;
post_itself.style.display = 'block';
})
}
django.views:
def edit(request, post_id):
try:
post = Post.objects.get(pk=post_id)
except Post.DoesNotExist:
return JsonResponse({"error": "Post not found."}, status=404)
if request.method == "POST":
edited_post = request.POST.get('post')
try:
post.post = edited_post
post.save()
except:
return JsonResponse({"error": "Editing the post did not work."}, status=404)
elif request.method == "GET":
return JsonResponse(post.serialize())
elif request.method == "PUT":
data = json.loads(request.body)
edited_post = data["edit_area"]
post.post = data["edited_post"]
post.save()
else:
return JsonResponse({"error": "Need a GET request."}, status=404)
html
{% for post in page_obj.object_list %}
<div class = "individual_posts">
<h5 id="p_user" class = "post_user">{{ post.user }}</h5>
<h6 id = "post_itself_{{ post.id }}" class="post_itself">{{ post.post }}</h6>
{% if post.user == request.user %}
<button id="{{ post.id }}" class="edit_button" value="{{ post.id }}">Edit</button>
{% endif %}
<textarea class="textarea" id="edit_area_{{ post.id }}" cols="220" rows="5"></textarea>
<button class="edit_save" id="save_{{ post.id }}">Save</button>
</div>
{% endfor %}
models.py serialization
def serialize(self):
return{
"id": self.pk,
"post": str(self.post),
"user": self.user.pk,
}
The GET request works correctly, but I am receiving the previously stated error from the PUT request. I think that it is because of the way I am getting the value through edited_post = data["edit_area"]. How do I correctly get access to the text within the textarea to pass to JSON?
In your save_edit PUT function you are using
post: JSON.stringify({
post: edit_area.value
})
But in your view you are looking for
data = json.loads(request.body)
edited_post = data["edit_area"]
post.post = data["edited_post"]
The JSON you are sending looks like
{"post": "Here's my edits"}
So you probably want something like:
data = json.loads(request.body)
post.post = data["post"]
Also - fetch uses "body" not "post" so you might want to amend your put function to
body: JSON.stringify({
post: edit_area.value
})

JSON POST and GET 404 (Not Found)

I am trying to create an API in Django but am receiving the following errors message in the JavaScript console.
GET http://127.0.0.1:8000/edit/undefined 404 (Not Found)
POST http://127.0.0.1:8000/edit/undefined 404 (Not Found)
Does anyone know how to fix this problem?
API url: path("edit/<int:post_id>", views.edit, name="edit")
views.py
def edit(request, post_id):
try:
post = Post.objects.get(user=request.user, pk=post_id)
except Post.DoesNotExist:
return JsonResponse({"error": "Post does not exist."}, status=404)
if request.method == "GET":
return JsonResponse(post.serialize())
else:
return JsonResponse({"error": "Need a GET request."}, status=404)
JavaScript
document.addEventListener('DOMContentLoaded', function(){
const editButtons = document.querySelectorAll('.edit_button');
for (const button of editButtons) {
button.addEventListener('click', () => edit_email());
}
});
function edit_email(id){
console.log("edit button is clicked")
document.querySelector('#post_itself').style.display = 'none';
document.querySelector('#date_and_time').style.display = 'none';
document.querySelector('#likes').style.display = 'none';
const textarea = document.createElement('textarea');
//get post
fetch(`/edit/${id}`)
.then(response => response.json())
.then(post => {
textarea.innerHTML = `${post.post}`
document.querySelector('#p_user').append(textarea);
})
//save the post
fetch(`/edit/${id}`,{
method: 'POST',
post: JSON.stringify({
post: textarea.value
})
})
}
HTML
{% for post in page_obj.object_list %}
<div class = "individual_posts">
<h5 id="p_user" class = "post_user">{{ post.user }}</h5>
<h6 id = "post_itself">{{ post.post }}</h6>
<h6 id="date_and_time" class = "post_elements">{{ post.date_and_time }}</h6>
<h6 id="likes" class = "post_elements">{{ post.likes }}👍</h6>
{% if post.user == request.user %}
<button id="editButton" class="edit_button">Edit</button>
{% endif %}
</div>
{% endfor %}
I think something might be wrong in the way I am passing in the id to the API, but I am not sure. Could the for loop in the HTML be causing the problem?
models.py
class User(AbstractUser):
followers = models.ManyToManyField("self", related_name="users_followers", symmetrical=False)
following = models.ManyToManyField("self", related_name ="who_user_is_following", symmetrical=False)
def serialize(self):
return{
"followers": self.followers,
"following": self.following
}
class Post(models.Model):
post = models.TextField()
user = models.ForeignKey(User, on_delete=models.CASCADE, default="")
likes = models.IntegerField(default=0)
date_and_time = models.DateTimeField(auto_now_add=True)
def serialize(self):
return{
"id": self.id,
"post": self.post,
"user": self.user,
"likes": self.likes,
"date_and_time": self.date_and_time
}
you call edit_email without id here:
button.addEventListener('click', () => edit_email());
of cause, after call you get /edit/undefined on this line:
fetch(`/edit/${id}`)
you don't send anything like id, I can imagine it should be something like this:
button.addEventListener('click', (event) => edit_email(event.target.value));
You will also need to pass the value property to the button as post.id assuming that the post object will have an id key in your for loop.
If you are getting a reference error you need to check if page_obj.object_list has an id key for all the posts.

How to stop Getting 405 error Method not allowed?

I am trying to make my django project to work but somehow I always come to get this error
Method Not Allowed (POST): /
I have tried using decorators like #csrf_exempt like in the django documentation as to not encounter csrf errors and yet I came to this error.Please tell me what's the problem with my code...
urls.py
from test.views import HomePageView,predict
urlpatterns = [
path('', HomePageView.as_view(), name="homepage"),
path('predict', predict, name="predict"),]
views.py
class HomePageView(Notif, TemplateView):
template_name = "homepage.html"
def predict(self, request, *args, **kwargs):
if request == 'POST':
text = self.request.get_json().get('message')
# check if text is valid
response = get_response(text)
message = {'answer': response}
return JsonResponse(message)
#method_decorator(csrf_exempt)
def dispatch(self, *args, **kwargs):
return super(HomePageView, self).dispatch(*args, **kwargs)
app.js
onSendButton(chatbox) {
var textField = chatbox.querySelector('input');
let text1 = textField.value
if (text1 === "") {
return;
}
let msg1 = { name: "User", message: text1 }
this.messages.push(msg1);
fetch( $SCRIPT_ROOT+'/predict',{
method: 'POST',
body: JSON.stringify({ message: text1 }),
mode: 'same-origin',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'X-CSRFToken':csrftoken,
},
})
.then(r => r.json())
.then(r => {
let msg2 = { name: "Sam", message: r.answer };
this.messages.push(msg2);
this.updateChatText(chatbox)
textField.value = ''
}).catch((error) => {
console.error('Error:', error);
this.updateChatText(chatbox)
textField.value = ''
});
}
homepage.html
<div class="container">
{% csrf_token %}
<div class="chatbox">
<div class="chatbox__support">
<div class="chatbox__header">
<div class="chatbox__image--header">
<img src="https://img.icons8.com/color/48/000000/circled-user-female-skin-type-5--v1.png" alt="image">
</div>
<div class="chatbox__content--header">
<h4 class="chatbox__heading--header">Chat support</h4>
<p class="chatbox__description--header">Hi. My name is Sam. How can I help you?</p>
</div>
</div>
<div class="chatbox__messages">
<div></div>
</div>
<div class="chatbox__footer">
<input type="text" placeholder="Write a message...">
<button class="chatbox__send--footer send__button">Send</button>
</div>
</div>
<div class="chatbox__button">
<button class="btn-light"><img src="./images/chatbox-icon.svg" width="45px" height="45px"/></button>
</div>
</div>
</div>
<script type="text/javascript">
$SCRIPT_ROOT='{{ request.path }}'
</script>
Method Not Allowed (POST): / - means your function is not accepting post methos it accpets only get or other safe methods.
you're not changing any state of your database so you don't have to use post request you can use get intead of post
class HomePageView(Notif, TemplateView):
template_name = "homepage.html"
#staticmethod
def predict(self, request, *args, **kwargs):
if request == "POST":
text = self.request.get_json().get("message")
# check if text is valid
response = get_response(text)
message = {"answer": response}
return JsonResponse(message)
#method_decorator(csrf_exempt)
def dispatch(self, *args, **kwargs):
return super(HomePageView, self).dispatch(*args, **kwargs)
and change your urls like this
urlpatterns = [
path('predict', HomePageView.predict, name="predict"),
]
and in your javascript change method post to get
fetch($SCRIPT_ROOT + '/predict', {
method: 'GET',
body: JSON.stringify({
message: text1
}),
mode: 'same-origin',
})

raise MultiPartParserError in Django2.2

I'm trying to post the form data using
'XMLHttprequest' to the django views and i'm getting 'A server error occurred. Please
contact the administrator.' in the browser console, and
i'm getting following error
raise MultiPartParserError('Invalid boundary in multipart: %s' % boundary.decode())
AttributeError: 'NoneType' object has no attribute 'decode' in my terminal.
The following is my code snippet.
<html><head><tile></title>
<body>
<form>
{% csrf_token %}
<input type="text" id="in" name="">
<input type="button" id='' value="submit" onclick="myfunction()">
</form>
<script type="text/javascript">
function myfunction() {
var emailId = document.getElementById('in').value;
var csrfToken = getCookie("csrftoken");
var myform = new FormData();
myform.append("email", emailId);
var xhttp = new XMLHttpRequest();
xhttp.open("POST", '{% url "log" %}', true);
xhttp.setRequestHeader('X-CSRFToken', csrfToken );
xhttp.setRequestHeader("Content-Type", "multipart/form-data;charset=utf-8");
xhttp.send(myform);
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
console.log(this.responseText)
}
};
}
</script>
<body>
</html>
This is my urls.py file
from django.contrib import admin
from django.urls import path
from zifapp import views
urlpatterns = [
path('admin/', admin.site.urls),
path('login/', views.login),
path('log', views.xmlhttprequest, name='log'),
]
and this is my views.py file
from django.http import JsonResponse
def xmlhttprequest(request):
print(request.POST.get('email', False))
return JsonResponse({'status':True}, safe=False)

Imagefield not saving in django cms plugin form working with AJAX

Hi I am new on django i was creating custom plugin in django cms it is the form other fields get saved easily, but the image field is not getting saved.
Here is my code let me know if I am missing something I am really stuck over here your help will be really appreciated.
models.py
class Blogs(models.Model):
name = models.CharField(u'Name',
blank=True,
default='',
help_text=u'Your name',
max_length=64,
)
description = models.TextField(u'Description',
blank=True,
default='',
help_text=u'Enter your Blog.',
)
comments = models.TextField(u'Short Description',
blank=True,
default='',
help_text=u'Short title of the Blog.',
)
images = models.ImageField(
upload_to='blog_image',
default='blog_image/black.png',
blank=True
)
# Meta, non-form data
contact_date = models.DateTimeField(
u'contact date',
blank=True,
default=timezone.now,
help_text=u'When this person completed the contact form.',
)
was_contacted = models.BooleanField(u'has been contacted?',
default=False,
help_text=u'Check this if someone has already reached out to this person.',
)
notes = models.TextField(u'contact notes',
blank=True,
default='',
help_text=u'Internal notes relating to contacting this person.',
)
referer = models.CharField(u'referring page',
blank=True,
default='',
help_text=u'This is the page the visitor was on before coming to the contact page.',
max_length=2048,
)
def send_notification_email(self):
subject.txt', {
'contact': self,
})
email_body = render_to_string('contacts/notification-body.txt', {
'contact': self,
})
try:
send_mail(
email_subject,
email_body,
settings.SERVER_EMAIL,
settings.MANAGERS,
fail_silently=(not settings.DEBUG)
)
except Exception:
if (settings.DEBUG):
raise
def save(self, *args, **kwargs):
if not self.pk:
try:
self.send_notification_email()
except:
pass
super(Blogs, self).save(*args, **kwargs)
def __unicode__(self):
return '%s (%s)' % (self.name, str(self.contact_date),)
class BlogPluginModel(CMSPlugin):
title = models.CharField(u'title',
blank=True,
help_text=u'Optional. Title of the widget.',
max_length=64,
)
def __unicode__(self):
return self.title
cms_plugins.py
class BlogPlugin(CMSPluginBase):
model = BlogPluginModel
name = _("Blog Form")
render_template = "blogs/_blogs_widget.html"
def render(self, context, instance, placeholder):
try:
path = context['request'].path
except:
path = ''
form = BlogAjaxForm(initial={'referer': path})
context.update({
"title": instance.title,
"form": form,
"form_action": reverse("blogging_form"),
})
return context
plugin_pool.register_plugin(BlogPlugin)
forms.py
class BlogBaseForm(ModelForm):
class Meta:
abstract = True
required_css_class = 'required'
verify_email = forms.EmailField(
label=u'Verify email',
help_text=u'Please retype your email address here.',
max_length=255,
required=True,
)
required_fields = []
class blogForm(BlogBaseForm):
images=forms.ImageField(help_text="Upload image: ", required=False)
class Meta:
model = Blogs
fields = [
'name','images', 'description', 'comments', 'referer',
]
widgets = {
'referer': forms.HiddenInput(),
}
required_fields = ['name', 'email', 'verify_email', ]
class BlogAjaxForm(BlogBaseForm):
images=forms.ImageField(help_text="Upload image: ", required=False)
class Meta:
model = Blogs
fields = ['name','images', 'description','comments','referer', ]
widgets = { 'referer': forms.HiddenInput(),}
view.py
class BlogFormView(FormView):
form_class = BlogBaseForm
template_name = 'contacts/contact_form.html'
def get_initial(self):
"""
still preserve this original HTTP_REFERER.
"""
initial = super(BlogFormView, self).get_initial()
initial['referer'] = self.request.META.get('HTTP_REFERER', ''),
return initial
def get_success_url(self):
page = get_object_or_404(
Page,
reverse_id='blog_form_submission',
publisher_is_draft=False
)
return page.get_absolute_url()
def form_valid(self, form):
self.object = form.save()
return super(BlogFormView, self).form_valid(form)
class AjaxableResponseMixin(object):
def __init__(self):
self.request = None
self.object = Blogs
def render_to_json_response(self, context, **response_kwargs):
data = json.dumps(context)
response_kwargs['content_type'] = 'application/json'
return HttpResponse(data, **response_kwargs)
def form_invalid(self, form):
response = super(AjaxableResponseMixin, self).form_invalid(form)
if self.request.is_ajax():
return self.render_to_json_response(form.errors) # , status=400)
else:
return response
def form_valid(self, form):
response = super(AjaxableResponseMixin, self).form_valid(form)
if self.request.is_ajax():
data = {
'pk': self.object.pk,
}
return self.render_to_json_response(data)
else:
return response
class BlogFormAjaxView(AjaxableResponseMixin, FormView):
form_class = BlogAjaxForm
http_method_names = [u'post']
template_name = 'contacts/_contact_widget.html'
form = BlogAjaxForm(http_method_names)
def get_success_url(self):
page = get_object_or_404(
Page,
reverse_id='blog_form_submission',
publisher_is_draft=False
)
return page.get_absolute_url()
def form_valid(self, form):
self.object = form.save(commit=True)
return super(BlogFormAjaxView, self).form_valid(form)
urls.py
urlpatterns = [
url(
r'^blogging_form/$',
BlogFormAjaxView.as_view(),
name='blogging_form'
),
url(r'^$', BlogFormView.as_view(), name='Blog_Form'),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
_blog_widget.html
{% load i18n static sekizai_tags %}
{% addtoblock "js" %}<script src="{% static 'blogs/scripts/Blogs.js' %}"></script>
{% endaddtoblock %}
{% addtoblock "css" %}
<link rel="stylesheet" href="{% static 'contacts/css/styles.css' %}">
{% endaddtoblock %}
{% addtoblock "js" %}
<script src="{% static 'http://malsup.github.com/jquery.form.js' %}"></script>
{% endaddtoblock %}
<div class="Blogs-plugin plugin">
<div class="inner">
<div class="Blog-form">
{% if title %}<h3>{{ title }}</h3>{% endif %}
<form method="post" action="{{ form_action }}" enctype="multipart/form-data">
{% csrf_token %}
{% for hidden in form.hidden_fields %}
{% if hidden.name == 'referer' %}
<input type="hidden" name="{{ hidden.name }}" value="{{ hidden.value }}">
{% endif %}
{% endfor %}
{% for visible in form.visible_fields %}
<div class="field-wrapper field-row half {{ visible.css_classes }}">
{{ visible.label_tag }}
<div class="help-text">{{ visible.help_text }}</div>
<div class="error empty"></div>
{{ visible }}
</div>
{% endfor %}
<input type="submit" value="Submit">
</form>
<div class="legend"><span class="required">*</span> Required field
</div>
<div class="success" style="display:none">Thank you, a member of our
team will contact you shortly, if appropriate.
</div>
<div class="errors" style="display:none"><span class="form-errors">
</span>
</div>
</div>
</div>
</div>
Blogs.js
(function($){
"use strict";
$(function(){
$('.Blogs-plugin input[type=submit]').on('click',
function(evt){
var $form = $(this).parents('form').eq(0);
function handleResponse(data){
if (data.pk) { // Success!
$form.siblings('.success').html(data.success).show(100);
$form.add('.legend').hide(100);
}
else { // Validation Issues...
//
// data will a dictionary like so:
// { 'field_name': ['error1', 'error2'], ... }
//
$form.find('.error').empty();
$.each(data, function(key, value){
var $field = $form.find('input[name='+key+']').first();
$field.parents('.fieldwrapper').find('.error').html(value.join(' '));
});
if (data.__all__) {
$form.siblings('.errors').find('.form-
errors').html(data.__all__.join(' '));
}
else {
$form.siblings('.errors').find('.form-errors').empty();
}
$form.siblings('.errors').show(100);
}
}
evt.preventDefault();
$form.siblings('.errors, .success').hide(100);
$.ajax({
type: 'POST',
url: $form.attr('action'),
data: $form.serialize(),
}).always(handleResponse);
});
});
}(window.jQuery));

Categories