Django ModelForm and AJAX usage - javascript

i am working on for a basic feedback system. I just want to submit feedback with ajax, for example if fields are empty ajax will return some error msg and update the div at the same page with no redirection. if everything is ok it will update the feedbacks div with the new one...
Here is my code
models.py
from django.db import models
# Create your models here.
class FeedBack(models.Model):
title = models.CharField(max_length=255)
description = models.TextField()
def __unicode__(self):
return self.title
class Meta:
ordering = ["-title"]
views.py
import json
from django.shortcuts import *
from django.template import RequestContext
from submission.forms import *
def feedback(request):
if request.method == "POST":
form = FeedBackForm(request.POST)
message = 'Oops!'
if(form.is_valid()):
message = request.POST['title']
return HttpResponse(json.dumps({'message': message}))
return render_to_response('index.html',
{'form':FeedBackForm()}, RequestContext(request))
urls.py
from django.conf.urls import patterns, include, url
from submission.views import *
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^feedback/', feedback, name='feed_back'),
)
index.html
<html>
<head>
<script type="text/javascript" src="../static/helper.js"></script>
</head>
<body>
<h1>Leave a Suggestion Here</h1>
<div class="message"></div>
<div>
<form id="feed_form" action="" method="POST">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit Feedback" />
</form>
</div>
</body>
</html>
helper.js
$(document).ready(function() {
$('#feed_form').submit(function() { // catch the form's submit event
$.ajax({ // create an AJAX call...
data: $(this).serialize(), // get the form data
type: $(this).attr('method'), // GET or POST
url: '', // the file to call
success: function(data) { // on success..
$('.message').html(data); // update the DIV
},
error: function(e, x, r) { // on error..
$('.message').html(e); // update the DIV
}
});
return false;
});
});

Related

Function to resend otp not working in django project

I have madefunction that resends otp when the 'resend Otp' lick is clicked. This is django project. The following are the codes that I wrote.
html (this page extends base.html)
<a class="resend-otp" href="#" onclick="ReSendOTP('{{user.username}}', 'resendOTPmess')" ><i id="resendOTPmess">Resend</i>OTP?</a>
<script type="text/javascript" src="{% static 'jquery-3.6.0.min.js' %}"></script>
<script type="text/javascript" src="{% static 'regd_ajax.js' %}"></script>
js file
function ReSendOTP(username, mess_id){
mess = document.getElementById(mess_id);
mess.innerText = "Sending...";
$.ajax({
type: 'GET',
url: '/user/resendOTP',
data: {usr:username},
success: function(data){
mess.innerText = data;
}
})
}
views.py
def resend_otp(request):
if request.method == 'GET':
get_user = request.GET['usr']
if User.objects.filter(username = get_user).exists() and not User.objects.get(username = get_user).is_active:
user = User.objects.get(username=get_user)
user_otp = random.randint(100000, 999999)
UserOtp.objects.create(user = user, otp = user_otp)
mess = f"Hello, {user.first_name}, \nYour OTP is {user_otp}\n Thanks!"
send_mail(
"Welcome to Solve Litigation - Verify your Email", #subject
mess, #message
settings.EMAIL_HOST_USER, # sender
[user.email], #reciever
fail_silently= False
)
return HttpResponse("Resend")
return HttpResponse("Can't Send OTP")
urls.py
from .views import resend_otp
path('resendOTP', resend_otp)
So here I am requesting a resend otp for the "username: rick.bhardwaj27#gmail.com" but I am getting the follwing error in the console
jquery-3.6.0.min.js:2 GET http://127.0.0.1:8000/user/resendOTP?usr=rick.bhardwaj27%40gmail.com 404 (Not Found)

How to do Live search Using Fetch Ajax Method In Django Python?

I am getting Post.match is not a function error when i do this :( Please help, i am a newbie in JavaScript part. (I am getting back an object so have to turn it into an array but still get this error after using the Objects.values Method)
My Views.py File:
from django.shortcuts import render
from django.http import HttpResponse, JsonResponse
from .models import Post
def Data(request):
items = Post.objects.all()
data = []
for qs in items:
I = {"title":qs.title,
"content": qs.content,
"image": qs.image.url,
}
data.append(I)
return JsonResponse({"data":data})
My HTML File:
{% extends 'blog/base.html' %}
{% load static %}
{% block content %}
<div class = 'w-100 text-center'>
<h1>Search Results</h1>
<form id = "search-form" autocomplete="off">
{% csrf_token %}
<input name = 'game' type="text" id = "search-input" placeholder= "Post Search..">
</form>
<div id = "results-box" class = "results-card">
</div>
</div>
{% endblock content %}
{% block js %}
<script defer src="{% static 'blog/S1.js' %}"> </script>
{% endblock js %}
My Java Script File:
console.log('Heelowwww')
const url = window.location.href
const searchForm = document.getElementById("search-form")
const searchInput = document.getElementById("search-input")
const resultsBox = document.getElementById("results-box")
const csrf = document.getElementsByName("csrfmiddlewaretoken")[0].value
options = {method: "GET",
headers: {
Accept: "application/json"
},
data:{
'csrfmiddlewaretoken': csrf,
}
}
const SearchPosts = async SearchIt => {
const res = await fetch("http://localhost:8000/data/",options)
const Posts = await res.json()
S = Object.values(Posts["data"])
let matches = S.filter(post =>{
const regex = new RegExp(`^${SearchIt}`, 'gi')
return post.match(regex)
})
console.log(matches)
}
searchInput.addEventListener('input', () => SearchPosts(searchInput.value))
My data Json Page:
Json Data Page
Here post.match(regex) your trying to call the match method on a js object. It seems you should be calling it on on of the string properties of it. Something like: post.title.match(regex).

Check django form validity and javascript

I'm using a django model form and I want to protect me from malicious user input (not just wrong input).
From my understanding django forms are enough secure: .is_valid() check user input, csfr protect from cross site forgery.
But this time my form isn't using action='/path/to/my/view' to call a django view, instead my submit button calls a javascript function and this function takes the data and calls a django view using ajax to access the database and then shows the results on screen.
So I don't think to be protected anymore (.is_valid() is not called, csfr is not sent). I'm right? and if so what I should do?
I think:
1) This is not a problem, the form is reasonable secure (why?)
2) Refactor the code and using a django view
3) Neither the django form validation is enough secure so anyway I should do something more (what?)
4) My javascript function is sending the data to a django view using ajax. I should use that data to instantializate a bound form and use .is_valid() on that, but anyway I'm not using csfr, right?
5) Using html validators (to me they don't look adapt to check against malicious input data)
6) Other?
Some code, to be complete but probabily you wont need it
my forms.py:
class NameListForm(forms.ModelForm):
class Meta:
model = Name
fields = ['namelanguage', 'nametype', 'gender']
widgets = {
'gender': forms.CheckboxSelectMultiple(),
}
My models.py:
class Name(models.Model):
name = models.CharField(_('nome'), max_length=50, default='')
namelanguage = models.ForeignKey(
NameLanguage, related_name='%(app_label)s_%(class)s_language',
verbose_name=_('linguaggio'), on_delete=models.PROTECT)
nametype = models.ForeignKey(
NameType, related_name='%(app_label)s_%(class)s_tipo',
verbose_name=_('tipo'), on_delete=models.PROTECT)
gender = models.ForeignKey(
Gender, related_name='%(app_label)s_%(class)s_gender',
verbose_name=_('sesso'), on_delete=models.PROTECT,
blank=True, null=True)
my template.html:
<form action="" method="post">
<div>
<div class="col-md-auto">
{{ name_list_form.namelanguage.label_tag }}<br />
{{ name_list_form.namelanguage }}
{{ name_list_form.namelanguage.errors }}
</div>
<div class="col-md-auto">
{{ name_list_form.nametype.label_tag }}<br />
{{ name_list_form.nametype }}
{{ name_list_form.nametype.errors }}
</div>
<div class="col-md-auto">
{{ name_list_form.gender.label_tag }}<br />
{{ name_list_form.gender }}<br />
{{ name_list_form.gender.errors }}
</div>
</div>
{{ name_list_form.non_field_errors }}
<div>
<button class="btn btn-primary" id='list_name' type="button" onclick="FilterBy()">{% trans "List Names" %}</button>
<button class="btn btn-primary" type="button" onclick="RandomNames()">{% trans "Random Names" %}</button>
</div>
{% csrf_token %}
</form>
My javascript.js:
function FilterBy() {
var language_id = document.getElementById("id_namelanguage").value;
var nametype_id = document.getElementById("id_nametype").value;
...
$.ajax({type: 'POST',
url: '/lists/get-list-name/',
data: {
language: language_id,
nametype: nametype_id,
...
},
success: function (lista) {
if (lista.result === 'OK') {
//do something
};
}
});
};
My views.py:
def GetListName(request):
if request.is_ajax():
language = request.POST.get('language')
nametype = request.POST.get('nametype')
# it makes sense to check validity here? and anyway I'm not using csfr, right?
# name_list_form = NameListForm({'namelanguage': language, 'nametype': nametype, etc})
# if name_list_form.is_valid():
...
return JsonResponse({'result': 'OK', 'data': my_dict})
CSRF and data validity are two different subject.
First, you can check for CSRF errors by sending the CSRF token in a request header check this.
Second, you can send your data the same way in JS than in a classic form.
// JS, don't forget to add your CSRF headers
$.ajax({
method: "post",
url: "...",
data: {
namelanguage: "foo",
nametype: "bar",
gender: "baz",
});
And just process your form as you do. You can throw an exception if you wan't to be sure you form was submitted from the JS script, but this won't assure you that it really does. Anybody can modify the client headers to make you think so.
# python
from django.http.response import HttpResponseBadRequest, HttpResponseNotAllowed
def GetListName(request):
if not request.is_ajax():
return HttpResponseNotAllowed()
form = NameListForm(data=request.POST)
if not form.is_valid():
return HttpResponseBadRequest()
# do stuff with your form
return JsonResponse({'result': 'OK', 'data': 'some data'})

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)

Change the data in div periodically on django template

I want to change the comments (data) appearing on my page periodically. I have referred to a question here, yet the data is not changing, it does on page refresh though.
Here's my code in views.py
def index(request):
count = Article.objects.all().count()
comments = Article.objects.values_list('content')[randint(0, count - 1)][0]
context = {
'current_date': datetime.now(),
'title': 'Home',
'comments': comments,
}
return render(request, 'index.html', context)
And urls.py
urlpatterns = [
url(r'^$', index, name='index'),
url(r'^about/$',about),
# url(r'^comments/$',ArticleCreateView.as_view(), name='comments'),
url(r'^admin/', admin.site.urls),
]
And index.html
<div>
<div id="comments">
{{ comments }}
</div>
</div>
<script>
var ALARM_URL = "{% url 'index' %}";
function refresh() {
$.ajax({
url: ALARM_URL,
success: function(data) {
$('#comments').html(data);
}
});
};
$(document).ready(function ($) {
refresh();
var int = setInterval("refresh()", 3000);
});
</script>
Your view index() returns an HTML page, so the argument data contains a whole HTML page.
You probably want to add a second view that returns JSON data only, maybe like this:
views.py
def index_data(request):
# here you return whatever data you need updated in your template
return JsonResponse({
'something_1': 0,
})
urls.py
url(r'^data$', index_data, name='index-data'),
And then in your AJAX call you do something like this:
url: "{% url 'index-data' %}",
success: function(data) {
$('#comments').html(data['something_1']);
}
Let us know if that helps.
EDIT
You probably also need to adjust your timer; pass it the function name, but without calling it and also not as a string (see the docs of setInterval):
$(document).ready(function ($) {
refresh();
setInterval(refresh, 3000);
});

Categories