Web text input save into database without form- Django Javascript - javascript

I have an sqlite3 database setup with django 1.6 where I want web users to be able to enter text and see it in 3 live tables (high, low and latest) all on the same page. The one page ideally should have text entry, voting, display of the three tables updated when new entries go in or are voted on, and a search if possible if all that gets sorted (personal project, not commercial). I am also on win7 64 if that matters...
Currently I have: a working database the three tables displaying in a web page without update and some web text input via js (and failing to save to the database in Django).
I shied away from forms at first, as they seem to want separate html pages for input. Asking an experienced django coder, he helped me out with some javascript for text entry on the page. He said I didn't need to do it via forms and POST, GET, as the text was just going in with the initial score of 0 and the current datetime.
My issue now is that I cannot get the entered text to save into the database without error.
Since I need to program this in 2-3 weeks and am new to django (and oblivious to javascript, though I've done some Processing with PHP), my questions are;
Am I missing something obvious with the text input save to database?
-and-
Is there a way to have all this using forms and GET, POST in one page
so I can avoid a lot of javascript (unless it is truly easier)?
I am going to start to try to build this with Forms at the moment, but hope for a bit of guidance on best practice from wiser heads.
Here's the code so far:
urls.py
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^i/$', 'entries.views.index'),
url(r'^add/(.*)$', 'entries.views.add'),
)
Models.py
from django.db import models
import datetime
from django.utils import timezone
class Entry(models.Model):
text = models.CharField(max_length=15)
score = models.IntegerField(default=0)
pub_date = models.DateTimeField('date published')
def __unicode__(self):
return self.text
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
was_published_recently.admin_order_field = 'pub_date'
was_published_recently.boolean = True
was_published_recently.short_description = 'Published recently?'
index.html
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
</head>
<body>
<ul>
{% for entry in latest_entry_list %}
<li>{{ entry.text }} &nbsp{{ entry.score }}</li>
{% endfor %}
</ul>
<ul>
{% for entry in high_entry_list %}
<li>{{ entry.text }} &nbsp{{ entry.score }}</li>
{% endfor %}
</ul>
<ul>
{% for entry in low_entry_list %}
<li>{{ entry.text }} &nbsp{{ entry.score }}</li>
{% endfor %}
</ul>
<style type="text/css" media="screen">
div h2 span { color: #ff0000; }
div span { color: #00ff00; }
#box { width: 400px; height: 400px; }
#h { color: #ff0000; }
</style>
<h3 id="h">title</h3>
<p>message: {{ text }}</p>
<input type="text" name="word" value="" id="input"/>
<script type="text/javascript" src="{{STATIC_URL}}post.js"></script>
</body>
post.js
console.log("hi from js");
$(document).ready(function() {
$("#input").bind("keypress", function(e) {
//enter key pressed
if (e.keyCode == 13) {
var args = {};
var text = $("#input").val();
$.get("/add/" + text, args).done(function(data) {
console.log("message: " + data);
});
}
});
});
views.py
from django.shortcuts import render
from django.http import HttpResponse
from entries.models import Entry
from django.db import models
import datetime
from django.utils import timezone
def index(request):
context = {
'latest_entry_list': Entry.objects.order_by('-pub_date')[:10],
'high_entry_list': Entry.objects.order_by('-score')[:10],
'low_entry_list': Entry.objects.order_by('score')[:10],
}
return render(request, 'entries/index.html', context);
def add(request, thingtoadd):
#created_date = models.DateTimeField('date published', default=datetime.now)
#created_score = '0'
#created_text = 'test'
#e = Entry(text=created_text, score=created_score,pub_date=created_date)
#e.save()
return HttpResponse('done')
I am unsure of defining the fields for populating the Entry....does the above look right?
I can uncomment the e=Entry(etc...) without error,
but when I uncomment the e.save(), the error is:
GET http://127.0.0.1:8000/add/a 500 (INTERNAL SERVER ERROR) jquery.min.js:4
send jquery.min.js:4
n.extend.ajax jquery.min.js:4
n.(anonymous function) jquery.min.js:4
(anonymous function) post.js:15
n.event.dispatch jquery.min.js:3
r.handle
I will be getting on with trying to do this in forms, but wonder if there is some good advice as to if that is possible - I would ideally like to avoid js extras as I am very unfamiliar with it and it would be another level of unknowns at this point. Any input greatly appreciated...

Your mistake in view function add:
created_date = models.DateTimeField('date published', default=datetime.now)
It must be value assign:
created_date = datetime.now()
Not field definition.
In advance you could specify auto_now_add=True in your model: https://docs.djangoproject.com/en/dev/ref/models/fields/#datefield
In that case field will be filled automatically.
Additional:
It is error in urls.py
You should do some fixes:
urls.py:
url(r'^add/$', 'entries.views.add'),
post.js
$("#input").bind("keypress", function(e) {
//enter key pressed
if (e.keyCode == 13) {
var text = $("#input").val();
var args = {'text': text};
$.get("/add/", args).done(function(data) {
console.log("message: " + data);
});
}
});
views.py
def add(request):
created_date = default=datetime.now()
created_score = '0'
created_text = request.GET.get('text')
e = Entry(text=created_text, score=created_score,pub_date=created_date)
e.save()
return HttpResponse('done')
Update - Solution
The solution in addition to the changes below was to add 'from datetime import datetime' in views....

Related

How to auto insert slashes in expiry date fields into django forms input

I want to insert a slash after 2 digit press like the same mechanism of MM/YY through Django forms input. The following has my code that is not working well.
Models.py
from django.db import models
from creditcards.models import CardExpiryField
class MyUser(models.Model):
cc_expiry = CardExpiryField('expiration date', null=True)
def __str__(self):
return self.cc_expiry
forms.py
from django import forms
from .models import MyUser
from django.forms import TextInput
class MyUserForm(forms.ModelForm):
class Meta:
model = MyUser
fields = ('cc_expiry')
widgets = {
'cc_expiry': TextInput(attrs={'placeholder': 'MM/YY'}),
}
views.py
def cc_page(request):
form = MyUserForm(request.POST or None)
context = {
"form": form
}
if form.is_valid():
form.save()
return render(request, 'cc_thanks.html')
return render(request, 'index.html', context)
index.html
{% load static %}
{% load widget_tweaks %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form id="regForm" method="post" action=" ">
{% csrf_token %}
<div class="tab">
{{ form.cc_expiry.errors }}
<p>{{ form.cc_expiry|add_class:"form-control" }}</p>
</div>
</form>
</body>
</html>
In the following has the simple HTML JS code for the automatic insert slash after 2 digit press and it's working fine. And the similar result I expected.
<input maxlength='5' placeholder="MM/YY" type="text" onkeyup="formatString(event);">
<script type="text/javascript">
function formatString(e) {
var inputChar = String.fromCharCode(event.keyCode);
var code = event.keyCode;
var allowedKeys = [8];
if (allowedKeys.indexOf(code) !== -1) {
return;
}
event.target.value = event.target.value.replace(
/^([1-9]\/|[2-9])$/g, '0$1/' // 3 > 03/
).replace(
/^(0[1-9]|1[0-2])$/g, '$1/' // 11 > 11/
).replace(
/^([0-1])([3-9])$/g, '0$1/$2' // 13 > 01/3
).replace(
/^(0?[1-9]|1[0-2])([0-9]{2})$/g, '$1/$2' // 141 > 01/41
).replace(
/^([0]+)\/|[0]+$/g, '0' // 0/ > 0 and 00 > 0
).replace(
/[^\d\/]|^[\/]*$/g, '' // To allow only digits and `/`
).replace(
/\/\//g, '/' // Prevent entering more than 1 `/`
);
}
</script>
I didn't get any better solution on how to create any js variable in Django forms and was able to retrieve data from there in the front as if I can show a slash after pressing 2 digits.
I have tried to create an input id into Django form attribute like in the following.
'cc_expiry': TextInput(attrs={'id': "example", 'placeholder': 'MM/YY'}),
But I didn't get the desired result.
I'll be grateful for any suggestions.
Thanks

Create a FlaskForm dropdown based on the query string value

class DownloadForm(FlaskForm):
products = service.get_products()
choices = [(product, product.replace('-', ' '))
for product in products]
application = SelectField(
'Application',
[DataRequired()],
choices=choices
submit = SubmitField('Submit')
#home.route('/downloads/<application_name>', methods=['GET', 'POST'])
def downloads():
download_form = DownloadForm()
My route will be downloads/application_name.
Can I send this routevalue "application_name" to the form to filter out the choices in the Download Form?
I'm new to entire flask and python.
You can use a factory function to use the parameter from the URL to do your database query. Based on this query, a form is then created that can be used within the route.
def download_form_factory(name):
products = [
'Archiver',
'Editor-1',
'Editor-2',
'Music-Player',
'Video-Player'
]
class DownloadForm(FlaskForm):
app = SelectField(
'Application',
choices= [
(product, product.replace('-', ' ')) \
for product in filter(lambda p: name.lower() in p.lower(), products)
]
)
submit = SubmitField('Download')
return DownloadForm
The following example uses an input field of type QuerySelectField from WTForms-SQLAlchemy to facilitate database queries. As you can see above, the functionality is also possible with a normal SelectField.
A number of products are added to the database which, in addition to their name, have an additional property build.
If the user selects a name on the index page, all products that have the selected name are available for selection. He can then choose between the offered versions.
The form is created inside a function. The name to be searched for is passed to this function as a parameter. This can then be used to create the database query.
def download_form_factory(name):
# Create a class of the form.
class DownloadForm(FlaskForm):
# Create the select field
app = QuerySelectField(
# with a label
'Application',
# and the database entries containing the given name as options
query_factory=lambda: Product.query.filter(Product.name.ilike(f'%{name}%')).all(),
# and a label for each of these options.
get_label=lambda p: '%s (Build %s)' % (p.name, p.build),
# An option must be selected by the user.
validators=[InputRequired()]
)
# Create the Submit button.
submit = SubmitField('Download')
# Return the created form class.
return DownloadForm
Within the endpoint, the function mentioned is used and an instance of the form is created, which can be used in the usual way.
#app.route('/download/<string:name>', methods=['GET', 'POST'])
def download(name):
# Create the form and an instance of it.
form = download_form_factory(name)(request.form)
if form.validate_on_submit():
# If the POST request is sent with valid information,
# the form data can be requested.
# The result is the selected database object.
print(form.app.data)
return render_template('download.html', **locals())
Here is the complete example.
Flask (app.py)
from flask import (
Flask,
render_template,
request,
)
from flask_wtf import FlaskForm
from flask_sqlalchemy import SQLAlchemy
from wtforms import SubmitField
from wtforms_sqlalchemy.fields import QuerySelectField
from wtforms.validators import InputRequired
app = Flask(__name__)
app.secret_key = b'your secret here'
db = SQLAlchemy(app)
class Product(db.Model):
__table_args__ = (db.UniqueConstraint('name', 'build'),)
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String, nullable=False)
build = db.Column(db.String, nullable=False)
# Create a class of the form.
def download_form_factory(name):
class DownloadForm(FlaskForm):
app = QuerySelectField(
'Application',
get_label=lambda p: f'{p.name} (Build {p.build})',
query_factory=lambda: Product.query.filter(Product.name.ilike(f'%{name}%')).all(),
validators=[InputRequired()]
)
submit = SubmitField('Download')
return DownloadForm
# Fill the database with sample data.
with app.app_context():
db.drop_all()
db.create_all()
products = [Product(name=f'Product-{str(i).zfill(2)}', build=f'{j}') \
for i in range(1, 21) for j in range(1,i+1)]
db.session.add_all(products)
db.session.commit()
#app.route('/')
def index():
products = Product.query.group_by(Product.name).order_by(Product.name).all()
return render_template('index.html', **locals())
#app.route('/download/<string:name>', methods=['GET', 'POST'])
def download(name):
# Create the final object of the form.
form = download_form_factory(name)(request.form)
if form.validate_on_submit():
# Inquire about the selected product.
print(form.app.data)
return render_template('download.html', **locals())
HTML (templates/index.html)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Index</title>
</head>
<body>
<ul>
{% for prod in products -%}
<li>{{prod.name}}</li>
{% endfor -%}
</ul>
</body>
</html>
HTML (templates/download.html)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Download</title>
</head>
<body>
<form method="post">
{{ form.csrf_token }}
<div>
{{ form.app.label }}
{{ form.app() }}
</div>
{{ form.submit() }}
</form>
</body>
</html>

Refresh a div in Django using JQuery and AJAX - Django ForLoop Issues

I have a django project that I'm trying to add a custom "online" state to (boolean field in a model). I want to refresh a div periodically to show if a user is now online. The div which is refreshed, with the class button-refresh, is in an included HTML file.
The issue is that the include doesn't work with my for loop in the original HTML file, none of the "professionals" data is retrieved from the server. I'm pretty new to django, my assumption is that the refresh_professionals.html file is retrieved with the ajax request and is entirely separate from the all_professionals.html and then included, without ever being a part of the for loop meaning that the {{ professional.professional_profile.online }} syntax doesn't work.
Any ideas on how to fix this issue? If there is a better way to do this, let me know. Thanks.
all_professionals.html
{% for professional in professionals %}
...
{{ professional.name }}
{% include 'professionals/refresh_professionals.html' %}
...
{% endfor %}
...
{% block postloadjs %}
{{ block.super }}
<script>var global_url = "{% url 'refresh_professionals' %}";</script>
<script src="{% static 'professionals/js/professionals.js' %}"></script>
{% endblock %}
refresh_professionals.html
<div class="col button-refresh">
{% if professional.professional_profile.online is True %}
<p class="custom-button mb-1 w-25 mx-auto">Chat</p>
{% else %}
<p class="custom-button-disabled mb-1 w-25 mx-auto">Unavailable</p>
{% endif %}
<p>{{ professional.price_chat }}/min</p>
</div>
professionals.js
$(document).ready(function(){
setInterval(function() {
$.ajax({
url: global_url,
type: 'GET',
success: function(data) {
$('.button-refresh').html(data);
}
});
}, 5000)
});
urls.py
urlpatterns = [
path('', views.view_all_professionals, name='view_all_professionals'),
path('refresh/', views.refresh_professionals, name='refresh_professionals'),
]
views.py
def view_all_professionals(request):
"""A view to return the professionals page"""
professionals = Professional.objects.all()
languages = Languages.objects.all()
context = {
'professionals': professionals,
'languages': languages,
}
return render(request, 'professionals/all_professionals.html', context)
def refresh_professionals(request):
"""A view to refresh the online button section"""
professionals = Professional.objects.all()
context = {
'professionals': professionals,
}
return render(request, 'professionals/refresh_professionals.html', context)
EDIT
I've followed Daniel's advice and am now returning a JSON object. This is the updated code
professionals.js
$(document).ready(function(){
setInterval(function() {
$.ajax({
url: global_url,
type: 'GET',
success: update_professionals,
});
}, 5000)
});
function update_professionals(response){
// unpack the response (context) from our view function:
var professionals = response.professionals;
// update html:
var i;
for (i = 0; i < professionals.length; i++) {
$('#professional-name' + i).text('professionals.name' + i);
};
};
views.py
def refresh_professionals(request):
"""A view to refresh the professionals section page"""
professionals = Professional.objects.all()
professionals = serializers.serialize("json", professionals)
context = json.dumps({
'professionals': professionals,
})
return HttpResponse(context)
The issue I'm facing now is referencing the professionals data. It's returning uncaught errors. The forloop is necessary because in my HTML I've got a series of IDs with a number attached to the end using a django forloop.counter. Any advice would be appreciated. Thanks.
Okay, lets assume we have a view function like so:
from django.http import HttpResponse
import json
def refresh_professionals(request):
"""A view to refresh the online button section"""
professionals = Professional.objects.all()
# convert to json friendly format:
professionals = ...
context = json.dumps({
'professionals': professionals,
})
return HttpResponse(context)
This assumes professionals now looks something like (the actual structure will obviously be different):
professionals = {"id":1, "name":"Jason"}
Now, in our js file we should have an ajax request like so (wrapped in a setInterval method, etc.):
$.ajax({
url: global_url,
type: 'GET',
success: update_professionals, // reference to an ajax-success function
});
And our success function like so:
update_professionals(response) {
// unpack the response (context) from our view function:
// use JSON.parse() to convert a string to json
var professionals = JSON.parse(response.professionals);
// update html:
$('#professional-name').text(professionals.name)
}
This assumes we have an HTML element like so:
<div id="professionals-name"> Sue </div>
The difference is we are using js to update the HTML on the fly instead of trying to re-render an HTML template likely will require a page refresh.

Trouble extracting multiple HTML DOM elements for AJAX with Django

I'm trying to implement a feature on a web app where I have a menu of pizzas, and the price listed on each card (feature taken from Bootstrap) dynamically updates depending on the style (regular/sicilian), size (small/large) and name (cheese/special) of pizza selected. I'm using a loop to create all the cards by querying the database using ORM in the backend, which takes all existing pizzas the restaurant owner adds, and makes a menu item for each one. Then, I'm aiming to extract the name, style, and size selections for each, and give a dynamic render of the price of that specific type of pizza in the price area of the card, using AJAX, before implementing the checkout functionality whereby a user buys that pizza. The problem is mainly that I'm unsure how to extract the name, style, and size selections given that the cards are implemented using a templating loop, and also I think there are a few small errors littered through my AJAX/backend. But I suspect the solution would be something to do with Javascript's ForEach() after I extract an array of the styles from the cards? I really don't know how I'd go about proceeding. My code is:
views.py:
from django.http import HttpResponse, Http404, HttpResponseRedirect, JsonResponse
from django.contrib.auth.models import User
from django.shortcuts import render
from .models import Topping, Size, Pizza, Sub, Pasta, Platter, Salad, pizza_styles, sizes
from django.urls import reverse
# Create your views here.
def index(request): # this home page will be the menu page
return render(request, "orders/index.html")
def pizza(request): # this home page will be the menu page
styles = [x[0] for x in pizza_styles]
# these lists have to be created because pizza_styles and sizes are naturally a list of tuples
propSizes = [x[0] for x in sizes]
context = {
'pizzas': Pizza.objects.all(),
'styles': styles,
'sizes': propSizes,
}
print(propSizes, styles, Pizza.objects.first().name) # diagnostic purposes
return render(request, "orders/pizza.html", context)
#below is the function I'm currently stuck on (the front end is the tough part I think)
def get_price(request):
style = request.GET.get('style', None)
size = request.GET.get('size', None)
name = request.GET.get('name', None)
data = {
'price' = Pizza.objects.filter(name=name, style=style, size=size).price
# get the pizza style, size, and type from the front end and query database on those filters to get price
}
return JsonResponse(data)
urls.py:
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index"),
path("pizza", views.pizza, name="pizza"),
path("get_price", views.get_price, name='get_price'),
]
pizza.html:
{% extends "orders/index.html" %}
{% block item %}
<main class="containerX">
<div class="row">
{% for pizza in pizzas %}
<div class="card border-primary mb-3" id="card">
<div class="card-body">
<h5 class="card-title" id="name">{{ pizza.name }}</h5>
<p class="card-text">
<select id="style">
{% for style in styles %}
<option value="{{ style }}">{{ style }}</option>
{% endfor %}
</select>
</p>
<p class="card-text">
<select id="size">
{% for size in sizes %}
<option value="{{ size }}">{{ size }}</option>
{% endfor %}
</select>
</p>
<p class="card-text" id="price"> price depending on selection </p>
Add to Cart
</div>
</div>
{% empty %}
<h2>No pizzas currently on offer. Sorry!</h2>
{% endfor %}
</div>
</main>
<script>
var size = document.querySelector('#size').value;
var name = document.querySelector('#name').textContent;
var style = document.querySelector('#style').value;
var price = document.querySelector('#price').value;
console.log(size, name, style, price)
// load default price set up in python too
(style.onchange || size.onchange) = function(){
// then send the ajax request
$.ajax({
url: '/get_price', // implement this url that will send back data
data: { // communication with the backend is to get the price from the database
'size': size,
'name': name,
'style': style,
},
dataType: 'json',
success: function (data) {
// simply update price here
price = data['price']
console.log(price)
}
});
};
</script>
{% endblock %}
I have a rudimentary understanding of how AJAX and Django work, and think my code for views, urls, and pizza.html are all, in principle, correct, but there are small implementation details I can't quite get a handle on, despite days of frustration.
It looks like your trying to listen to the change event on the actual value but you need to listen to the Dom node. Also ensure that you are including jquery before your JavaScript as $.ajax is a jquery function. Try changing your JavaScript to the following:
<script>
var size = document.querySelector('#size');
var name = document.querySelector('#name').textContent;
var style = document.querySelector('#style');
var price = document.querySelector('#price').value;
console.log(size, name, style, price)
// load default price set up in python too
(style.onchange || size.onchange) = function(e){
var styleValue = e.target.value;
var sizeValue = e.target.value;
// then send the ajax request
$.ajax({
url: '/get_price', // implement this url that will send back data
data: { // communication with the backend is to get the price from the database
'size': sizeValue,
'name': name,
'style': styleValue,
},
dataType: 'json',
success: function (data) {
// simply update price here
price = data['price']
console.log(price)
}
});
};
</script>
Let me know if you have further problems and I’ll try help.

How to save HTML5 geolocation data to python Django admin?

Is it possible to save the javascript html5 geolocation latitude and longitude to the django admin when user uses the geolocation website. The web page goal is to save the user's longitude and latitude values so that the data can be accessed later on when user signs in again.
I found a similar question being asked in stackoverflow years ago but there hasn't been any answer. The link is : Save JavaScript GeoLocation data to Django admin page
It would be great if there this an answer based on this code link.
Another option I read about is to create a html form and set the form to be autopopulated by jQuery from data produced by the javascript html5 geolocation. Again this is quite complicated for a beginner like me.
I would appreciate any bit of help whether by code, tutorial, blog post, examples or links. I don't expect all the programming code to be provided (although I do learn better from examples) but it would help if there are some material/example I could go to, to implement my programming tasks. Thank you.
I am currently up to here with my progress but still am unable to post the latitude and longitude to the django admin page:
code is as following:
The structure of the django project is as follows:
-ajax
- __pycache__
- migrations
- __pycache__
0001_initial.py
__init__.py
- static
- css
- bootstrap.css
- fonts
- js
- script.js
- templates
- ajax
- base.html
- index.html
- __init__.py
- admin.py
- apps.py
- models.py
- tests.py
- urls.py
- views.py
-server
- __pycache__
- __init__.py
- settings.py
- urls.py
- views.py
- wsgi.py
-db.sqlite3
-manage.py
index.html
{% extends 'ajax/base.html' %}
{% block body %}
<p>Click the button to get your coordinates.</p>
<button onclick="getLocation()">Get Your Location</button>
<p id="demo"></p>
<button type="button" id="btn_submit" class="btn btn-primary form-control" disabled>Submit</button>
{% endblock %}
script.js
var pos;
var $demo;
function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
} else {
$demo.text("Geolocation is not supported by this browser.");
}
}
function showPosition(position) {
pos = position;
var { latitude, longitude } = pos.coords;
$demo.html(`Latitude: ${latitude}<br>Longitude: ${longitude}`);
$('#btn_submit').attr("disabled", null);
}
$(document).ready(function() {
$demo = $("#demo");
$('#btn_submit').on('click', function() {
var data = pos.coords;
data.csrfmiddlewaretoken = $('input[name=csrfmiddlewaretoken]').val();
$.post("/ajax/", data, function() {
alert("Saved Data!");
});
});
});
base.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" name="viewport" content="width=device-width, initial-scale=1">
{% load static %}
<link rel="stylesheet" type="text/css" href="{% static 'ajax/css/bootstrap.css' %}"/>
</head>
<body>
{% csrf_token %}
<nav class="navbar navbar-default">
<div class="container-fluid">
</div>
</nav>
<div class="col-md-3"></div>
<div class="col-md-6 well">
<h3 class="text-primary">Python - Django Simple Submit Form With Ajax</h3>
<hr style="border-top:1px dotted #000;"/>
{% block body %}
{% endblock %}
</div>
</body>
<script src = "{% static 'ajax/js/jquery-3.2.1.js' %}"></script>
<script src = "{% static 'ajax/js/script.js' %}"></script>
</html>
models.py
from django.db import models
# Create your models here.
class Member(models.Model):
latitude = models.DecimalField(max_digits=19, decimal_places=16)
longitude = models.DecimalField(max_digits=19, decimal_places=16)
views.py (ajax)
from django.shortcuts import render, redirect
from .models import Member
def index(request):
return render(request, 'ajax/index.html')
def insert(request):
member = Member(latitude=request.POST['latitude'], longitude=request.POST['longitude'])
member.save()
return redirect('/')
urls.py (ajax)
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index, name="index"),
url(r'^insert$', views.insert, name="insert")
]
views.py (server)
from django.shortcuts import redirect
def index_redirect(request):
return redirect('/ajax/')
urls.py (server)
from django.conf.urls import url, include
from django.contrib import admin
from . import views
urlpatterns = [
url(r'^$', views.index_redirect, name="index_redirect"),
url(r'^ajax/', include("ajax.urls")),
url(r'^admin/', admin.site.urls),
]
It "POST"s the data but it does not appear in the django admin. I trawled many websites searching for answers why but still haven't found any. Thank you again for your help.
I have used jQuery and Ajax to submit the longitude and latitude data to any model you want to store these data in.
in your model.py:
from django.contrib.auth import User
class UserGeoLocation(models.Model):
user = models.OneToOneField(User)
latitude = models.FloatField(blank=False, null=False)
longitude = models.FloatField(blank=False, null=False)
for your view.py
def save_user_geolocation(request):
if request.method == 'POST':
latitude = request.POST['lat']
longitude = request.POST['long']
UserGeoLocation.create(
user = request.user
latitude= latitude,
longitude = longitude,
)
return HttpResponse('')
now that we have the view we can setup a url endpoint to submit the post request
url('^abc/xyz/$', appname.views.save_user_geolocation)
and Finally for the actual form,
$(document).on('submit', '#id', function(e){
e.preventDefault();
$.ajax(
type='POST',
url = 'abc/xyz',
data : {
lat:position.coords.latitude,
long: position.coords.longitude
csrfmiddlewaretoken:$('input[name=csrfmiddlewaretoken]').val()
},
});
for the last step, lets say you used the js code from the example you linked, then you can assign these coordinates value to variables that will be submitted with the post request that gets triggered when the user clicks on the button, the id here is the id of the form you want to submit the data from, and the e.PreventDefault is to stop the page from reloading when you post the data. Finally, the csrf token is required by django to able to submit the form.

Categories