Django Form not saving to MySQL - django-forms

Hello and Thank you in advance:
I have a form that is not saving the input data into the MySQL database. I am not getting an error, it simply isn't saving that data...
My Model:
from django.db import models
from django.forms import ModelForm
class DraftInput(models.Model):
player_id = models.CharField(max_length=5)
def __unicode__(self):
return self.player_id
class DraftInputForm(ModelForm):
class Meta:
model = DraftInput
My View:
def player_draft_input_view(request):
if request.method == 'POST':
form = DraftInputForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/draft/')
else:
form = DraftInputForm()
return render_to_response('baseball/basic_draft_pick.html', { 'form': form, }, context_instance=RequestContext(request))
My template:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Basic Draft Pick Page</title>
</head>
<body>
<form action="" method="POST">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Draft" />
</form>
</body>
</html>
I bet this is something really simple and I am going to kick myself, but I have been looking at this code for about 5 hours now...
Thank you,
dp

I knew it was something I was just missing! in the code above:
return render_to_response('baseball/basic_draft_pick.html', { 'form': form, }, context_instance=RequestContext(request))
should be:
return render_to_response('baseball/basic_draft_pick.html', { 'form': form }, context_instance=RequestContext(request))
no comma after { 'form': form }
I feel stupid, but gratified that I caught the error and not someone else...
Thank you all!!
dp

Related

Flask, WTForms - send the whole form using ajax

I am wondering how to send the whole wtform using ajax request (this one does not work):
function addReport(e){
e.preventDefault();
var serializeData = $('form').serialize();
$.ajax({
type:'GET',
url:'/reports_list',
data: serializeData,
success:function(result){
},
async: false
});
}
I have one main form, which includes another:
Reports = FieldList(FormField(ReportsForm))
The idea is to render the form under form, in case user wants to add another one. In short, it should just copy this underform and clone it, then renders to the main one.
How can I pass the entire form in ajax request?
It seems to me that you are trying to nest form elements. So you only send the innermost form. The validation errors are also not displayed when the form is sent via AJAX.
I think you can follow your approach more easily if you add the necessary form fields by cloning with JavaScript without submit.
The following example breaks the nested forms into fieldsets.
If a fieldset is to be added, the previous one is cloned and the necessary attributes are adapted to the requirements.
When removing, the last one is removed.
from flask import (
Flask,
render_template,
request
)
from flask_wtf import FlaskForm
from wtforms import FieldList, FormField, StringField, SelectField
from wtforms.validators import DataRequired
app = Flask(__name__)
app.secret_key = 'your secret here'
class ReportForm(FlaskForm):
class Meta:
csrf = False
title = StringField('Name', [DataRequired()])
lang = SelectField('Language', choices=[('cpp', 'C++'), ('py', 'Python'), ('text', 'Plain Text')])
class ReportsForm(FlaskForm):
reports = FieldList(FormField(ReportForm), min_entries=1)
#app.route('/reports', methods=['GET', 'POST'])
def reports():
form = ReportsForm(request.form)
if form.validate_on_submit():
for report in form.reports.data:
print(report)
return render_template('reports.html', **locals())
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Reports</title>
</head>
<body>
<form name="my-form" method="post">
{{ form.csrf_token }}
{% for subform in form.reports -%}
<fieldset name="subform">
{% for field in subform -%}
<div>
{{ field.label() }}
{{ field() }}
{% if field.errors -%}
<ul class="errors">
{% for error in field.errors -%}
<li>{{ error }}</li>
{% endfor -%}
</ul>
{% endif -%}
</div>
{% endfor -%}
</fieldset>
{% endfor -%}
<button id="btn-less" type="button">Less</button>
<button id="btn-more" type="button">More</button>
<button type="submit">Submit</button>
</form>
<script type="text/javascript">
(function() {
const btnMore = document.querySelector('#btn-more');
btnMore.addEventListener('click', function() {
// Clone the previous fieldset element.
const subform = document.querySelector('fieldset[name="subform"]:last-of-type');
const newform = subform.cloneNode(true);
// Remove possible validation error messages.
const errors = newform.querySelector('.errors');
errors && errors.remove();
// Update the necessary attributes.
const fields = newform.querySelectorAll('input, select');
fields.forEach(field => {
const attrName = field.name;
field.name = field.id = attrName.replace(/^(.*)-([0-9]+)-(\w+)$/g, (...args) => {
return [args[1], Number(args[2]) + 1, args[3]].join('-');
});
field.value = '';
const labels = newForm.querySelectorAll(`label[for="${attrName}"]`);
labels.forEach(label => label.setAttribute('for', field.id));
});
// Add the new fieldset.
subform.after(newform);
});
const btnLess = document.querySelector('#btn-less');
btnLess.addEventListener('click', function() {
const subforms = document.querySelectorAll('fieldset[name="subform"]');
if (subforms.length > 1) {
// Remove the last of the fieldset elements.
subforms[subforms.length - 1].remove();
}
});
})();
</script>
</body>
</html>

how to use ajax for django login

I want to create a ajax login that sends data and renders the html without refreshing the page here.
I followed some of the already answered solutions here,
but it's throwing me a 400 error.
how do i solve the error, and have the login info such as username displayed in the designated layer (.login_div)?
could you help me out?
{% load staticfiles %}
<html>
<head>
<link rel='stylesheet' href='{% static "css/normalize.css" %}' />
<link rel='stylesheet' href='{% static "css/skeleton.css" %}' />
<link rel='stylesheet' href='{% static "css/index.css" %}' />
</head>
<body>
<script src='{% static "js/jquery.js" %}'></script>
<div class="login_div"></div>
<form id="login_form" method="post" action="{% url 'login' %}">
{% csrf_token %}
<div class="field-wrap">
<label>
Email Address
</label>
<input name="username">
</div>
<div class="field-wrap">
<label>
Password
</label>
<input name="password">
</div>
<p class="forgot">Forgot Password?</p>
<button class="button button-block"/>Log In</button>
</form>
<script>
$('form').on('submit', function(e) { e.preventDefault()
$.ajax({
type:"POST",
url: '../login/',
data: $('#login_form').serialize(),
success: function(response){
$('.login_div').text(username)
// do something with response
response['result']; // equals 'Success or failed';
response['message'] // equals 'you"re logged in or You messed up';
}
});
});
</script>
</body>
</html>
and views.py
from django.shortcuts import render
from django.contrib.auth.models import User
from django.contrib.auth import authenticate, login
from django.http import HttpResponse, HttpResponseBadRequest
import json
def ajax_login(request):
print(request.method)
print(request.POST)
if request.method == 'POST':
username = request.POST.get('username', '').strip()
password = request.POST.get('password', '').strip()
print("U: %r / P: %r" % (username, password))
if username and password:
# Test username/password combination
user = authenticate(username=username, password=password)
# Found a match
if user is not None:
# User is active
if user.is_active:
# Officially log the user in
login(self.request, user)
data = {'success': True}
else:
data = {'success': False, 'error': 'User is not active'}
else:
data = {'success': False, 'error': 'Wrong username and/or password'}
return HttpResponse(json.dumps(data), content_type='application/json')
# Request method is not POST or one of username or password is missing
return HttpResponseBadRequest()
def index(request):
return render(request, "index.html")

Django - Allow User to Edit Profile and then Show Updated Profile fields

I have the form populating with the user profile information, but when I click save, it doesn't actually update.
Any clues/hints as to which part I need to modify is greatly appreciated.
Thanks in advance!
views.py
def profile_view(request):
user = request.user
form = EditProfileForm(initial={'first_name':user.first_name, 'last_name':user.last_name})
context = {
"form": form
}
return render(request, 'profile.html', context)
def edit_profile(request):
user = request.user
form = EditProfileForm(request.POST or None, initial={'first_name':user.first_name, 'last_name':user.last_name})
if request.method == 'POST':
if form.is_valid():
user.first_name = request.POST['first_name']
user.last_name = request.POST['last_name']
user.save()
return HttpResponseRedirect('%s'%(reverse('profile')))
context = {
"form": form
}
return render(request, "edit_profile.html", context)
forms.py
class EditProfileForm(forms.ModelForm):
first_name = forms.CharField(label='First Name')
last_name = forms.CharField(label='Last Name')
class Meta:
model = User
fields = ['first_name', 'last_name']
edit_profile.html
{% extends "base_site.html" %}
{% block content %}
<h1>Edit Profile</h1>
<form method="POST" action="/accounts/profile/" class="" />
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Save</button>
</form>
{% endblock %}
urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^register/$', 'accounts.views.registration_view', name='auth_register'),
url(r'^login/$', 'accounts.views.login_view', name='auth_login'),
url(r'^logout/$', 'accounts.views.logout_view', name='auth_logout'),
url(r'^profile/$', 'accounts.views.profile_view', name='profile'),
url(r'^profile/edit/$', 'accounts.views.edit_profile', name='edit_profile'),
]
The action in your form is POSTing to profile_view and not edit_profile and your forms are self closing so they aren't being POSTed correctly.
Change this:
<form method="POST" action="/accounts/profile/" class="" />
To this:
<form method="POST" action="/accounts/profile/edit" class="" >
Or even better, use the django url template tag:
<form method="POST" action="{% url 'edit_profile' %}" class="" >

google.maps.places.Autocomplete requests Location too many times in Firefox

in my website, I have a singn_up-form and use the Google-Api to give the user some suggestions. The API requests the location of the user once in Internet-Explorer. But if I try Firefox, the requests are looped until I click "Standort immer Freigeben" - it means "always accept".
function initialize() {
autocomplete = new google.maps.places.Autocomplete(
(document.getElementById('autocomplete')),
{ types: ['geocode'] });
}
The code is loaded at document.ready and contains more code, but this snippet also reproduces the error.
Does anyone has some ideas?
Try this :
put the apis in your <head></head>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?v=3&sensor=false&libraries=places"></script>
put this in your body tag:
<label for="autocomplete">Please Insert an address:</label>
<br>
<input id="autocomplete" type="text" size="100">
put this in your onload function:
var input = document.getElementById('autocomplete');
new google.maps.places.Autocomplete(input);
this is my code :
var input = document.getElementById('autocomplete');
new google.maps.places.Autocomplete(input);
<html>
<head>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?v=3&sensor=false&libraries=places"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
<body>
<label for="autocomplete">Please Insert an address:</label><br>
<input id="autocomplete" type="text" size="100">
</body>
</html>
You might have kept some onfocus attribute as given in Google Maps API Example
<input id="autocomplete" placeholder="Enter your address" onFocus="geolocate()" type="text"></input>
OR
If you don't require keeping bounds for places suggestions, you may want to remove it
OR
If you need to set bounds for suggestions keep some condition to not call location consent every time, if user gives permission.
Please keep your condition in geolocate() function
Issue is happening only in Mozilla FireFox
What you want to do is this:
function handlePermission() {
navigator.permissions.query({name:'geolocation'}).then(function(result) {
if (result.state == 'granted') {
geoBtn.style.display = 'none';
} else if (result.state == 'prompt') {
geoBtn.style.display = 'none';
navigator.geolocation.getCurrentPosition(revealPosition,positionDenied,geoSettings);
} else if (result.state == 'denied') {
geoBtn.style.display = 'inline';
}
});
}
then put handlePermission(); after your callback function receives permission

Django with Ajax and jQuery

I would like after clicking on one of the many Item shown a window with his description (single item description).
How to create this using Ajax and jQuery with Django?
model:
class Item(models.Model):
name = models.CharField(max_length=50)
slug = models.SlugField()
price = models.DecimalField(max_digits=5, decimal_places=2)
desc = models.TextField()
views:
def item_list(request):
items = Item.objects.all()[:6]
return render_to_response('items.html', {'items':items}, context_instance=RequestContext(request))
def single_item(request, slug):
item = Item.objects.get(slug=slug)
return render_to_response('single.html', {'item':item}, context_instance=RequestContext(request))
template:
<!-- Single item description: -->
<div id="description">
<img src="/site_media/images/photo.png">
<div id="item_description">
<input name="add" type="button" id="add" value="Add to Cart">
<p class="title">Single Item name</p>
<p class="description"><span>Description:</span>
This is single item description
</p>
</div>
</div>
<!-- All item: -->
<div id="item">
{% for i in items %}
<div class="item">
<img src="/{{ i.image.url }}" />
<p>
<span> {{ i.name }} </span>
<span> {{i.price}} </span>
</p>
</div>
{% endfor %}
</div>
</div>
</div>
If you want to use ajax to refresh your page, you'll need to do three things:
Add an entry to urls.py for the ajax call (or add a condition to your view function to process the request if it's ajax)
Add the javascript block to make the ajax call and update the html/text with the new data
Add the code in your views.py to handle the ajax call and respond with json data
urls.py
...
url(r'/ajax-view-single/)/$', 'ajax_single_item', name='app_name_ajax_single_item'),
html/js
<script type="text/javascript" src="/js/json2.js"></script>
$("#view-single-item").click(function () {
try {
// get slug from html
var slug = "";
var data = {
slug: slug
};
$.get('{% url app_name_ajax_single_item %}', data, function(data){
// your data returned from django is in data
alert(data.item_name);
}, 'json');
//$('#error').hide();
}
catch(err) {
$('#error').html(err);
$('#error').show();
}
return false;
});
views.py
from django.http import HttpResponse
from django.utils import simplejson
from django.shortcuts import get_object_or_404
def ajax_single_item(request):
'''gets single item'''
if not request.is_ajax():
return HttpResponse(simplejson.dumps({'result': False}))
# get slug from data
slug = request.GET.get('slug', None)
# get item from slug
item = get_object_or_404(Item, slug=slug)
return HttpResponse(simplejson.dumps({
'result': True,
'item_name': item.name,
'item_price': item.price,
'item_desc': item.desc,
'item_slug': item.slug
}))

Resources