How to use GeoDjango Pointfield in Form? - django

I wanted to know to to use the PointField widget that is automatically generated from a Django form.
I am using the generic views for this (CreateView)
This is what my model looks like.
from django.contrib.gis.db import models
class Post(models.Model):
title = models.CharField(max_length=60)
text = models.CharField(max_length=255)
location = models.PointField(geography=True, null=True, blank=True)
objects = models.GeoManager()
The form is then automatically generated for me and I just call it in my view. As such:
{{ form.as_p }}
This is the output of that piece of code.
<form method="post">
<input type='hidden' name='csrfmiddlewaretoken' value='wVZJIf7098cyREWe3n3jiZinPdbl8nEe' />
<p><label for="id_title">Title:</label> <input id="id_title" maxlength="60" name="title" type="text" /></p>
<p><label for="id_text">Text:</label> <input id="id_text" maxlength="255" name="text" type="text" /></p>
<p><label for="id_location">Location:</label> <style type="text/css">
#id_location_map { width: 600px; height: 400px; }
#id_location_map .aligned label { float: inherit; }
#id_location_div_map { position: relative; vertical-align: top; float: left; }
#id_location { display: none; }
.olControlEditingToolbar .olControlModifyFeatureItemActive {
background-image: url("/static/admin/img/gis/move_vertex_on.png");
background-repeat: no-repeat;
}
.olControlEditingToolbar .olControlModifyFeatureItemInactive {
background-image: url("/static/admin/img/gis/move_vertex_off.png");
background-repeat: no-repeat;
}
</style>
<div id="id_location_div_map">
<div id="id_location_map"></div>
<span class="clear_features">Delete all Features</span>
<textarea id="id_location" class="vSerializedField required" cols="150" rows="10" name="location"></textarea>
<script type="text/javascript">
var map_options = {};
var options = {
geom_name: 'Point',
id: 'id_location',
map_id: 'id_location_map',
map_options: map_options,
map_srid: 4326,
name: 'location'
};
var geodjango_location = new MapWidget(options);
</script>
</div>
</p>
<input type="submit" value="Create" />
</form>
In the head tags I import an OpenLayers script from
http://cdnjs.cloudflare.com/ajax/libs/openlayers/2.13.1/OpenLayers.js
However, the page will not show anything for the pointfield. (The other fields work just fine).
In chromedevtools it shows this error
Uncaught ReferenceError: MapWidget is not defined
For this line of code
var geodjango_location = new MapWidget(options)
Basically I want to know if there is someother javascript library I should be linking to or am I missing something else?
I've looked through the documentation on GeoDjango forms, but don't know what else to try
https://docs.djangoproject.com/en/dev/ref/contrib/gis/forms-api/

Add this to the head section:
<head>
{{ form.media }}
</head>

I have a related problem with my Admin UI. My solution is just a reference for your problem. Firefox browser was blocking the loading of mix http/https http://openlayers.org/api/2.13/OpenLayers.js because my geodjango site forces https.
One solution is to download the OpenLayer.js into my geodjango project static directory, and add the following line to my CustomGeoModelAdmin:
class MyCustomGeoModelAdmin(....):
openlayers_url = '/static/mygeodjangoproject/OpenLayers.js'
#property
def media(self):
"Injects OpenLayers JavaScript into the admin."
media = super(MyCustomGeoModelAdmin, self).media
media.add_js([self.openlayers_url])
return media
and voilà, my admin site now shows a Geographical Map for the Point Field.

Related

Insert multi selected option text into pg using django

For instance, I used Django to pull certain unique number data from my database.
Then I created dropdown with search using select2. And used jQuery for search functionality. With this I could select multiple unique number at a time and with output printed in textarea field.
my question is, how to insert multiple selected options in Postgrel using Django.
I need help in backend as i m newbie in django
I tried to served everywhere but I could see only php guide.
this is my frontend code
enter code here
Search Models for CId
{% csrf_token %}
{% for x in searchmodels %}
{{ x.cid }}
{% endfor %}
You can add multiple CID and click Add
-->
<br>
<div class="resultbox">
<h2>Selected CIDs</h2>
<textarea name="" id="cidresult" cols="70" rows="15"></textarea><br><br>
<input type="button" id="addcid" value="Submit" onclick="searchresult();">
</div>
</form>
</tr>
<style>
.resultbox{
position: fixed;
left: 30%;
top: 10px;
width: 550px;
background-color: antiquewhite;
padding-left: 30px;
padding-right: 10px;
}
</style>
Now here is my jQuery code
$(document).ready(function()
{
$('#selectedcid').select2({
placeholder:'Search CID...',
closeOnSelect:false
});
$('#selectedcid').on('change',function()
{
var resultdisplay=$('#selectedcid option:selected').text();
$('#cidresult').val(resultdisplay).join(',');
})
});
this is how it looks nowenter image description here

How to show the information in the same page where I am submitting form in django

I am trying to submit a form and get the result in the same page where I have created the form . But , can't get the values in the same page . But , whenever I am trying to take the value in a different page it's working.
My views.py file :
def home(request):
words = request.GET['text']
count = len(words.split())
context = {'count':count}
return render(request,'index.html',context)
My index.html file:
<div class="container">
<h3 style="display:inline-block; text-transform: capitalize; padding-top: 10px; border-bottom: 2px solid #e5e5e5;">Word counting app</h3>
<h5 style="padding-top: 40px;text-transform: capitalize;">enter your word below to count</h5>
<div class="row">
<div class="col-lg-6">
<form method="" action="">
<textarea name="text" cols="30" rows="7"></textarea>
<button type="submit" style="padding: 6px 28px; border: none; background:orange; margin-top: 10px;">Submit</button>
</form>
<p>{{count}</p>
</div>
</div>
</div>
Add form method 'GET' to your html and remove action attribute. If there are no action provided in the form element, it will be posted to same url as your page.
<form method="GET">

Django - how to correctly upload and handle a file?

I have the following model of an apk, the package_name and sdk_version will be taken by parsing the apk file which the user will upload. I also need to save the path of the uploaded file in my model, that's why I used FilePathField, however I'm not sure it's the correct way to handle the task. I saw some examples where FileField was used, and it got me confused, when do I use which?
Another point to make, since a path is just a string, I can save it as Charfield, can't I?
class Apk(models.Model):
package_name = models.CharField(max_length=45, unique=True)
sdk_version = models.CharField(max_length=45, unique=True)
apk_file = models.FilePathField()
To upload the file I used this guide.
views.py:
def upload_apk(request):
handle_uploaded_file(request.FILES['file'], str(request.FILES['file']))
return HttpResponse("Upload Successful")
def handle_uploaded_file(file, filename):
if not os.path.exists('policies/upload/'):
os.mkdir('policies/upload/')
with open('policies/upload/' + filename, 'wb+') as destination:
for chunk in file.chunks():
destination.write(chunk)
apk_path = "/policies/upload/" + filename
apkf = APK(apk_path)
package_name = apkf.get_package()
sdk_version = apkf.get_androidversion_name()
template.html:
<form id="uploadApkForm" action="{{ request.build_absolute_uri }}uploadApk/" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<div class="input-element" style="border:1px solid black; background:white; padding:2px">
<input type="file" name="file" style="width:100%" required>
</div>
<div style="width:100%;">
<div style="position: absolute;
left: 50%;
bottom: 0px;
transform: translate(-50%, -50%);
margin: 0 auto;">
<input id="uploadBtn" type="submit" value="Ok" class="btn btn-primary" style="width:75px; margin-right:10px" />
<input id="clsBtn" type="button" class="btn btn-primary" value="Cancel" style="width:75px; "/>
</div>
</div>
</form>
I saw different examples where ModelForm was used, and I'm not sure if my way to upload the file is good.
Can you please point out what is the best way to upload a file and save it's path in data base?
In my opinion, it is probably easiest to use a FileField. Using a filefield, it will actually save the file at a specific location, as well as allow you to use the file as an object rather just a simple path. With the filefield, it will also give you the ability to access the path.

React Component using codemirror not sending all data on form submission

I am using django, react and react-codemirror2 in my project where a user can input SQL code. I am running into an issue where only part of the text from textarea exists in request.POST. I am finding that mostly just part of the last line of the textarea is sent. I am baffled.
React component
import React from 'react'
import {UnControlled as CodeMirror} from 'react-codemirror2'
import DjangoCSRFToken from 'django-react-csrftoken'
class SQLForm extends React.Component{
componentDidMount() {
let textarea = document.getElementsByTagName('textarea')[0]
textarea.setAttribute('name', 'sql');
}
render(){
return(
<div>
<form action="" method="POST">
<DjangoCSRFToken/>
<CodeMirror
options={{
mode: 'text/x-mssql',
theme: 'material',
lineNumbers: true
}}
onChange={(editor, data, value) => {
}}
/>
<br/>
<button type="submit">Submit</button>
</form>
</div>
)
}
}
export default SQLForm
super simple django view (just to see what is submitted)
def index(request):
if 'sql' in request.POST:
print(request.POST['sql'])
return render(request, 'react.html', {})
else:
return render(request, 'react.html', {})
for example, in the text area, if type in the following
SELECT *
FROM whatever
WHERE something=2
print(request.POST['sql']) shows the following at the console
=2
And for completeness, this is the textarea tag when the page loads
<textarea autocorrect="off" autocapitalize="off" spellcheck="false" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;" tabindex="0" name="sql"></textarea>
got this to work by not worrying about CodeMirror being in the form. Instead I used state to capture the last value from the CodeMirror onChange function and then assigned that to the value attribute of the button. Switched the name attribute being in the textarea to being in the button itself.
import React from 'react'
import {UnControlled as CodeMirror} from 'react-codemirror2'
import DjangoCSRFToken from 'django-react-csrftoken'
class SQLForm extends React.Component{
constructor(props){
super(props)
this.updateText = this.updateText.bind(this);
this.state = {
sql_text: ''
}
}
updateText(value){
this.setState((prevState)=>({sql_text:value}))
}
render(){
return(
<div>
<CodeMirror
options={{
mode: 'text/x-mssql',
theme: 'material',
lineNumbers: true
}}
onChange={(editor, data, value) => {
{this.updateText(value)}
}}
/>
<form action="" method="POST">
<DjangoCSRFToken/>
<button type="submit" value={this.state.sql_text} name="sql">Submit</button>
</form>
</div>
)
}
}
export default SQLForm

Delete via AJAX results in CSRF token missing or incorrect

Django 1.10
DetailView renders "detail.html".
In "detail.html" I place "Delete" button. In other words, I want users to be able to press "Delete" exactly from "detail.html" when they see the object itself.
So, on pressing "Delete" button I call FrameDelete via AJAX.
Could you help me understand why I get the error: CSRF token missing or incorrect.
class Frame(models.Model):
title = models.CharField(max_length=100,
null=False,
blank=False,
default="",
unique=True,
verbose_name="Заголовок")
def get_delete_url(self):
return reverse("frame:frame_delete", kwargs=self.get_kwargs())
class FrameDelete(ActionDeleteMixin, DeleteView):
model = Frame
success_url = reverse_lazy("empty")
template_name = 'general/ajax/ajax_confirm_delete.html'
class ActionDeleteMixin():
def get_context_data(self, **kwargs):
context = super(ActionDeleteMixin, self).get_context_data(**kwargs)
context["action"] = self.object.get_delete_url()
return context
js
function post_delete(){
$.ajax({
method: 'POST',
url: "{{ object.get_delete_url }}",
success: redirect_to_frame_list,
error: fail
});
}
function fail(jqXHR, textStatus, errorThrown){
debugger;
}
ajax_confirm_delete.html
{% block content %}
<form action="{{ action }}" method="post">{% csrf_token %}
<p>Are you surely want to delete "{{ object }}"?</p>
<input id="confirm" type="submit" value="Confirm" />
</form>
{% endblock %}
In the browser when inspecting element in Chrome:
<form action="/frame/18/delete/" method="post"><input type="hidden" name="csrfmiddlewaretoken" value="bHZxf62Oa9WrapuacCm8gLVNlY2nJHllfwqPsAHoPO0RS8z8NnhMSv5tnIFQZKPP">
<p>Are you surely want to delete "18: Michael's news"?</p>
<input id="confirm" type="submit" value="Confirm">
</form>
**
In the browser when stop at the debugger breakpoint in fail function
"
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="robots" content="NONE,NOARCHIVE">
<title>403 Forbidden</title>
<style type="text/css">
html * { padding:0; margin:0; }
body * { padding:10px 20px; }
body * * { padding:0; }
body { font:small sans-serif; background:#eee; }
body>div { border-bottom:1px solid #ddd; }
h1 { font-weight:normal; margin-bottom:.4em; }
h1 span { font-size:60%; color:#666; font-weight:normal; }
#info { background:#f6f6f6; }
#info ul { margin: 0.5em 4em; }
#info p, #summary p { padding-top:10px; }
#summary { background: #ffc; }
#explanation { background:#eee; border-bottom: 0px none; }
</style>
</head>
<body>
<div id="summary">
<h1>Forbidden <span>(403)</span></h1>
<p>CSRF verification failed. Request aborted.</p>
</div>
<div id="info">
<h2>Help</h2>
<p>Reason given for failure:</p>
<pre>
CSRF token missing or incorrect.
</pre>
<p>In general, this can occur when there is a genuine Cross Site Request Forgery, or when
<a
href="https://docs.djangoproject.com/en/1.10/ref/csrf/">Django's
CSRF mechanism</a> has not been used correctly. For POST forms, you need to
ensure:</p>
<ul>
<li>Your browser is accepting cookies.</li>
<li>The view function passes a <code>request</code> to the template's <code>render</code>
method.</li>
<li>In the template, there is a <code>{% csrf_token
%}</code> template tag inside each POST form that
targets an internal URL.</li>
<li>If you are not using <code>CsrfViewMiddleware</code>, then you must use
<code>csrf_protect</code> on any views that use the <code>csrf_token</code>
template tag, as well as those that accept the POST data.</li>
<li>The form has a valid CSRF token. After logging in in another browser
tab or hitting the back button after a login, you may need to reload the
page with the form, because the token is rotated after a login.</li>
</ul>
<p>You're seeing the help section of this page because you have <code>DEBUG =
True</code> in your Django settings file. Change that to <code>False</code>,
and only the initial error message will be displayed. </p>
<p>You can customize this page using the CSRF_FAILURE_VIEW setting.</p>
</div>
</body>
</html>
"
You should add the csrf_exempt or generate the csrf token with ajax