Capturing from a html POST form a model in Django - python

The truth i'm new to django and i would like to know how I can capture a value of an input type = hidden in a view of django, using request.POST [ 'address'] so that it can enter a value in my model in this case I want to fill my field direction but does not receive any data appears in the database as empty. This is the code I have so far:
views.py
def formularioLleno(request):
form = InformationForm()
if request.method == 'POST':
form = InformationForm(request.POST or None)
if form.is_valid():
form.ubicacion = request.POST['direccion']
form.save()
#return redirect('formas.index')
return HttpResponseRedirect(reverse('index'))
else:
form = InformationForm()
data = {
'form': form,
}
return render_to_response('forma_form.html', data, context_instance=RequestContext(request))
forms.py
from django import forms
from .models import forma
class InformationForm(forms.ModelForm):
class Meta:
model = forma
fields = ('nombre', 'telefono')
models.py
class forma(models.Model):
nombre = models.CharField(verbose_name='nombre', max_length=50, unique=False)
telefono = models.CharField(verbose_name='telefono', max_length=10, unique=False)
ubicacion = models.CharField(verbose_name='ubicacion', max_length=15, unique=False)
forma_form.html
<div id="formularios">
{% block form_content %}
<form action="" method="POST">
{% csrf_token %}
{{ form.as_p }}
<div id="ubicacion"></div>
<input type="hidden" id="direccion" name="direccion" value="hello">
<button type="submit" onclick="alerta()">Contactar</button>
</form>
{% endblock form_content %}

The reason you aren't seeing the input is that the form field "direccion" is not a member of the class InformationForm. When you load data from the request with form = InformationForm(request.POST or None) the direccion field is not captured.
I would recommend adding a new member to the InformationForm form (direccion), and set the widget to HiddenInput (read more about Widgets here: https://docs.djangoproject.com/en/1.10/ref/forms/widgets/)
This keep the input hidden on the form but will pass the information back to the View. You can then remove the hard coded hidden input HTML from your template.

Related

ModelForm saving value of submit button to database

I have a form in my project that just wouldnt grab whatever the user typed in and im stumped for why
no matter what i typed into the input field, the string 'Post' is what gets saved into the database, which is the value of the submit button, nd whatever i changed the value to is also what gets saved.
model
class Post(models.Model):
post = models.TextField(max_length=250)
author = models.CharField(max_length=64)
date_time = models.DateTimeField(default=timezone.now, blank=True)
def __str__(self):
return f"{self.author}, {self.date_time}, {self.post}"
form
class NewPostForm(ModelForm):
class Meta:
model = Post
fields = ['post']
views.py
def index(request):
newpostform = NewPostForm()
if request.user.is_authenticated:
username = request.user.get_username()
if request.method == 'POST':
post = Post(author=username)
newpostform = NewPostForm(request.POST,request.FILES, instance=post)
if newpostform.is_valid():
post = newpostform.save()
return render(request, "network/index.html")
return render(request, "network/index.html", {
"newpostform": newpostform
})
html
> <form action="{% url 'index' %}" method="post">
> {% csrf_token %}
> <div>
> {{ newpostform }}
> </div>
> <input id='post-btn' class="btn btn-primary" name="post" type="submit" value="Post">
> </form>

MultiValueDictKeyError when I trying to post image

When I trying to add image from admin panel all OK, but when I trying to add image from site, I have this error: image of error. When I trying to post Detail without image, I have the same problem. Before this wasn't.
views.py:
def new_detail(request):
if request.user.is_authenticated:
if request.user.is_superuser:
if request.method == 'POST':
car = request.POST['car']
author = request.user
detail = request.POST['detail']
price = request.POST['price']
description = request.POST['description']
image = request.FILES['images']
detail = Detail(car = car, author = author, detail = detail, price = price, description = description, images = image)
detail.save()
return redirect('/new_detail/')
else:
return redirect('/login/')
return render(request, 'shop/new_detail.html')
new_detail.html:
{% extends 'base.html' %}
{% block content %}
<div class="content container">
<div class="row">
<div class="col-md-8">
<div class=".signin">
<form action="" method="POST">
{% csrf_token %}
<h3>Автомобіль: </h3>
<select name="car">
<option selected>Audi A8 D2 3.3 TDI</option>
<option>Audi A8 D2 3.7</option>
...
...
...
<h3>Ціна: </h3><textarea name="price"></textarea>
<h3>Фотки: </h3><input type="image" name="images" />
<p>
<input type="submit" value="Опублікувати" />
</form>
</div>
</div>
</div>
models.py:
from django.db import models
class Detail(models.Model):
author = models.ForeignKey(
'auth.User',
on_delete=models.CASCADE,)
car = models.CharField(max_length=100)
detail = models.TextField()
description = models.TextField()
price = models.CharField(max_length=30)
images = models.ImageField(upload_to='details', null = True, blank = True)
def __unicode__(self):
return self.detail
def __str__(self):
return self.detail
The first problem is that you are missing enctype="multipart/form-data" from your form tag in the template. See the docs on file uploads for more info.
<form action="" method="POST" enctype="multipart/form-data">
Secondly, your view doesn't handle the case when data is missing from the form. Instead of doing request.POST['detail'] you should be checking if 'detail' in request.POST or using request.POST.get('detail').
However it would be very time consuming to check every field individually. You should look at Django forms and model forms, which can handle a lot of this for you.
from django import forms
class DetailForm(forms.ModelForm):
class Meta:
model = Detail
fields = ['car', 'author', 'detail', 'price', 'description', 'images']
Then your view will be something like
from django.contrib.auth.decorators import user_passes_test
#user_passes_test(lambda u: u.is_superuser)
def new_detail(request):
if request.method == 'POST':
form = DetailForm(request.POST)
if form.is_valid():
detail = form.save()
return redirect('/new_detail/')
else:
form = DetailForm(request.POST)
return render(request, 'shop/new_detail.html', {'form': form})
You can use the form to simplify your template as well:
<form action="" method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form }}
</form>
See the docs on rendering fields manually if you need more control in the template.

Django - How to filter dropdown based on user id?

I'm not sure how to filter dropdown based on user id.
Not I want for user id 2.
I want exactly like this for user id 2.
Model
#python_2_unicode_compatible # only if you need to support Python 2
class PredefinedMessage(models.Model):
user = models.ForeignKey(User)
list_name = models.CharField(max_length=50)
list_description = models.CharField(max_length=50)
def __str__(self):
return self.list_name
class PredefinedMessageDetail(models.Model):
predefined_message_detail = models.ForeignKey(PredefinedMessage)
message = models.CharField(max_length=5000)
View
class PredefinedMessageDetailForm(ModelForm):
class Meta:
model = PredefinedMessageDetail
fields = ['predefined_message_detail', 'message']
exclude = ('user',)
def predefined_message_detail_update(request, pk, template_name='predefined-message/predefined_message_detail_form.html'):
if not request.user.is_authenticated():
return redirect('home')
predefined_message_detail = get_object_or_404(PredefinedMessageDetail, pk=pk)
form = PredefinedMessageDetailForm(request.POST or None, instance=predefined_message_detail)
if form.is_valid():
form.save()
return redirect('predefined_message_list')
return render(request, template_name, {'form':form})
html file
{% extends "base.html" %}
{% load i18n %}
{% block content %}
<form method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>
{% endblock %}
You can do it in view itself using
form = PredefinedMessageDetailForm(request.POST or None, instance=predefined_message_detail)
form.fields["predefined_message_detail"].queryset= PredefinedMessage.objects.filter(user=request.user)
But filtering happens based on request.user so it should be logged in.Consider that also. Hope this helps

Django forms: Combination of HTML form fields and forms.py fields in same model

My application has a form which requires me to pre-fill certain values in form fields using information extracted from a user's Twitter account after a successful login. Here's what my form looks like after the user has successfully logged in from his/her Twitter account (the 'Name' field is pre-filled with the full name associated with the user's twitter account):
models.py
from django.db import models
from django.core.validators import RegexValidator
from django.contrib.auth.models import User
class Evangelized(models.Model):
full_name = models.CharField(max_length=128)
email = models.EmailField()
mobile_no = models.CharField(unique=True, max_length = 10, validators=[RegexValidator(regex='^\w{10}$', message='Mobile number should be strictly of 10 digits.')])
twitter_url = models.CharField(unique=True, max_length=128)
GENDER_CHOICES = (('M', 'Male'), ('F', 'Female'), ('U', 'Unisex/Parody'))
gender = models.CharField(choices=GENDER_CHOICES, max_length = 128)
HTML
<form id="evangelized_form" method="post" action="/rango/fillform/">
NAME: <input type = "text" name = "name" value = "{{user.get_full_name}}"><br>
{% csrf_token %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% for field in form.visible_fields %}
{{ field.errors }}
<b>{{ field.help_text }}</b><br>
{{ field }}<br><br>
{% endfor %}
<input type="submit" name="submit" value="Submit" />
</form>
forms.py
class EvangelizedForm(forms.ModelForm):
#full_name = forms.CharField(help_text="Full Name")
email = forms.CharField(help_text="Email ID")
mobile_no = forms.CharField(help_text="Mobile number")
twitter_url = forms.CharField(help_text="Twitter URL")
gender = forms.CharField(widget=forms.RadioSelect(
choices=Evangelized.GENDER_CHOICES), help_text="Gender", max_length = 128)
Note that I have included the full_name attribute in my models.py, but have excluded it from forms.py. I have included the Name field in my HTMl page instead as follows:
NAME: <input type = "text" name = "name" value = "{{user.get_full_name}}"><br>
Thus, value = "{{user.get_full_name}}" pre-fills the Name field in the form.
views.py
def fillform(request):
if request.method == 'POST':
form = EvangelizedForm(request.POST)
if form.is_valid():
form.full_name = request.POST['name']
form.save(commit=True)
return index(request)
else:
form.errors
else:
form = EvangelizedForm()
context = RequestContext(request,
{'request': request,
'user': request.user, 'form':form})
#return render(request, 'rango/fillform.html', {'form': form, 'context_instance':context})
return render_to_response('rango/fillform.html',
context_instance=context)
Now, I want the Name field value to be stored in the database just like all other form field values. However, except the full_name attribute, all other form attributes get stored in the database on submitting the form.
I think I'm not catching the Name form field value from my HTML page in my view properly. Any solutions?
EDIT 1:
Based on the suggestions of a commenter, I made the following changes in views.py:
def fillform(request):
if request.method == 'POST':
form = EvangelizedForm(request.POST)
if form.is_valid():
form.save(commit=True)
return index(request)
else:
form.errors
else:
#form = EvangelizedForm()
form = EvangelizedForm(initial={'full_name': request.user.get_full_name()})
context = RequestContext(request,
{'request': request,
'user': request.user, 'form':form})
#return render(request, 'rango/fillform.html', {'form': form, 'context_instance':context})
return render_to_response('rango/fillform.html',
context_instance=context)
However, I'm now getting the following error:
'WSGIRequest' object has no attribute 'get_full_name'
What seems to be wrong here?

same row multiple times in a form in django

have a form by which user can enter details about some expenses but i want to have same row in the form again and again but couldn't find out how to do that :
if you see figure above this forms works well for 1 row of data , saves well but with more then 1 row it cant . Can someone suggest any way to do that . Below are the codes :
models.py
from django.db import models
class Expenditure(models.Model):
exp_date = models.DateField("Expenditure_Date")
description = models.CharField(max_length=500)
amount = models.FloatField(default=0)
currency = models.CharField(max_length=15,default="USD")
class Meta:
unique_together = ('exp_date', 'description',)
def __unicode__(self):
return self.description
forms.py
from django import forms
from moni.models import Expenditure
from django.contrib.admin.widgets import AdminDateWidget
class ExpenditureForm(forms.ModelForm):
#exp_date = forms.DateField(help_text="Date")
exp_date = forms.DateField(widget=AdminDateWidget)
description = forms.CharField(max_length=500)
amount = forms.FloatField(initial=0)
currency = forms.CharField(widget=forms.HiddenInput(), initial="USD")
# An inline class to provide additional information on the form.
class Meta:
# Provide an association between the ModelForm and a model
model = Expenditure
fields = ('exp_date', 'amount', 'description')
views.py
from django.template import RequestContext
from django.shortcuts import render_to_response
from moni.models import Expenditure
from moni.forms import ExpenditureForm
def add_expenditure(request):
context = RequestContext(request)
if request.method == 'POST':
form = ExpenditureForm(request.POST)
if form.is_valid():
form.save(commit=True)
return index(request)
else:
print form.errors
else:
form = ExpenditureForm()
return render_to_response('moni/add_expenditure.html', {'form': form}, context)
add_expenditure.html
{% extends 'moni/base.html' %}
{% block title %}Add Shipment {% endblock %}
{% block body_block %}
<h1>Add a Expenditure</h1>
<p id="p_hide"> I am a paragraph to be hidden</p>
<button id ="btn1">Hide Paragraph</button>
<form id="expenditure_form" method="post" class="vDateField" action="/moni/add_expenditure/">
{% csrf_token %}
<table border=1>
<tr><th><label >Date:</label></th> <th><label for="id_description">Description:</label></th><th><label for="id_amount">Amount:</label></th></tr>
<tr><td><input class="vDateField" name="exp_date" size="10" type="text" /></td><td>{{form.description}}</td><td>{{form.amount}}<input id="id_currency" name="currency" type="hidden" value="MYR" /></td></tr>
<tr><td><input class="vDateField" name="exp_date" size="10" type="text" /></td><td>{{form.description}}</td><td>{{form.amount}}<input id="id_currency" name="currency" type="hidden" value="MYR" /></td></tr>
</table>
<input type="submit" name="submit" value="Create Expenditure" />
</form>
{% endblock %}
For that use Formeset function, Here is the idea for print form in multiple times
ExpenditureFormSet = formset_factory(ExpenditureForm, extra=3,)
And views like
if formset.is_valid():
for data in formset.cleaned_data:
And pass it into {formset} So html will print the extra 3 forms
You should use ModelFormSets instead of ModelForm.
And if you're going to add forms dynamically, use corresponding JavaScript plugin (since management form should be changed every time new form is added).

Categories

Resources