request.POST.get returns NULL - python

I'm trying POST my text value from my HTML form to Django view but always get NONE as a result.
Initially, I was trying to fetch value by request.POST which threw "MultiValueDictKeyError" then I changed my code to request.POST.get which is returning None
HTML file
{% csrf_token %}
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1" style="margin-top: 5px">
<ul class="nav navbar-nav">
<li class="dropdown" style="padding-right: 10px">
<select class="form-control" id="sel1" style="font-family: Courier">
{% for environment in env_list %}
<option name="NewEnvName"
value="{{ environment.Env_name }}">{{ environment.Env_name }}</option>
{% endfor %}
</select>
</li>
</ul>
<ul class="nav navbar-nav">
<li class="dropdown" style="font-family: Courier;font-size: 20px;color: ivory">
<input type='radio' name='CobranSelection' value="CobrandName" checked/>
<label for="edit-radios-lorem-tortor-erat" class="option"
>Cobrand
Name | </label>
<input type='radio' name='CobranSelection' value="CobrandId"/>
<label for="edit-radios-lorem-tortor-erat" class="option"
>Cobrand
Id </label>
</li>
</ul>
<div class="form-group">
<input type="text"
style="margin-top: -1px;font-family: Courier;width: 210px;margin-right: -10px"
class="form-control"
name="cobrand" placeholder="Eneter Cobrand detail here">
<button type="submit" class="btn btn-default"
style="margin-top: -31px;font-family: Courier;margin-left: 230px">
Submit
</button>
</div>
</div><!-- /.navbar-collapse -->
</form>
view.py
from django.shortcuts import render, HttpResponseRedirect
from .models import Environments
from django.db.models import Q
import cx_Oracle
def knowcobrand(request):
value_type = request.POST.get('CobranSelection')
cobrand_value = request.POST.get('cobrand')
env = request.POST.get('NewEnvName')
print(value_type)
print(cobrand_value)
print(env)
return render(request, 'CobrandView/CobrandInDepth.html')
urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
url('login', views.login),
url('Home', views.fetch_all_env),
url('AddEnvironment', views.add_environment),
url('GetEnvironment', views.GetEnvironment),
url('ReadDb', views.readdb),
url('LearnCobrand', views.learncobrand),
url('ReadCobrand',views.knowcobrand)
]
I'm posting my HTML and views.py for reference. Could anyone of you please help me by pointing out my mistake.

add this attribute to your form :
enctype="multipart/form-data"
like this :
<form action="" method="post" enctype="multipart/form-data">
and attention in view side file field use request.FILES

Related

Django UserCreationForm and Bootstrap Forms Layouts

I am trying to extend the UserCreationForm using a Bootstrap layout style for the field username. After the input tag in the registration form, I would like to add a div element like an example that I have readapted from the Bootstrap page: i.e. suggesting the user to enter the same username as the company domain.
Let's focus to the bare minimum. The form readapted from Bootstrap is:
<form class="row gy-2 gx-3 align-items-center method="POST" action="{% url 'register' %} ">
<div class="col-auto">
<div class="input-group">
<input type="text" name="username" class="form-control" placeholder="your.username" id="id_username">
<div class="input-group-text">#company.domain.com</div>
</div>
</div>
<div class="col-auto">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form>
Which produces the following:
For the moment, I am using only {{form.as_p}} in my html template file:
<form class="row gy-2 gx-3 align-items-center method="POST" action="{% url 'register' %} ">
{{form.as_p}}
<div class="col-auto">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form>
And I don't know how to add the <div class="input-group-text">#company.domain.com</div> part embedded in a <div class="input-group">...</div> block.
My actual forms.py is a bit more complex, but readapted for this minimum example it contains the widget attributes as follows:
class SignupForm(UserCreationForm):
username = forms.CharField(label="",
widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'your.username'}))
class Meta:
model = User
fields = (
'username',
)
Without additional libraries, is there a way to extend the widget attributes? Is it even possible to use {{form.as_p}} as I am currently doing or should I use another method?
If you want to use only {{ form.as_p }} with bootstrap then you need to install django-bootstrap.
Install it using pip:
pip install django-bootstrap4
After installation, add it in INSTALLED_APPS in settings.py file.
INSTALLED_APPS = [
'bootstrap4',
]
And in templates, you need to load it.
{% load bootstrap4 %}
{% bootstrap_messages %}
<form class="row gy-2 gx-3 align-items-center method="POST" action="{% url 'register' %} ">
{% csrf_token %}
{% bootstrap_form form %} # added `form` here. we don't need to use with as_p.
<div class="form-group">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form>
This is the way you can use bootstrap along with {{ form.as_p }}
OR
Try another way:
Simply you can use {{ form.username }} inside an input tag in template.
For Example:
<input type="text" value="{{ form.username }}">
<form class="row gy-2 gx-3 align-items-center method="POST" action="{% url 'register' %} ">
<div class="col-auto">
<div class="input-group">
<input type="text" name="username" class="form-control" placeholder="your.username" id="id_username" value="{{ form.username }}"> #Added here
<div class="input-group-text">#company.domain.com</div>
</div>
</div>
<div class="col-auto">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form>

Django not redirecting to next page

I don't know what's happening with my code, once a user that is not authenticated tries to access a page and it redirects to the login page, I can see the next parameter in the browser but after the user logins, it takes the user to the default LOGIN_REDIRECT_URL and not the next page. Also on the template next returns none, so seems the template is not getting thee next value, but in the url it shows the /?next=, thanks in advance.
urls.py
from django.contrib import admin
from django.urls import path, include
from django.contrib.auth import views as auth_views
from blog import views
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.HomeView.as_view(),name="index"),
path('accounts/login/', auth_views.LoginView.as_view(), name='login'),
path('accounts/logout/', auth_views.LogoutView.as_view(next_page='/'), name='logout'),
path('accounts/profile/', views.ProfileView.as_view(), name='profile'),
]
registration/login.html
{% extends 'app/base.html' %}
{% block link %} id="active" {%endblock%}
{% block content %}
<div class="row">
<div class="col-md-3">
</div>
<div class="col-md-6">
<div class="jumbotron" id="font">
{% if next %}
{% if user.is_authenticated %}
<h2 class="customtext" align="center">Your account doesn't have access to this page. To proceed,
please login with an account that has access.</h2>
{% else %}
<h2 class="customtext" align="center">Please login.</h2>
{% endif %}
{% else %}
<h2 class="customtext" align="center">Enter your login details.</h2>
{% endif %}
<form action="{% url 'login' %}" method="POST">
{%csrf_token%}
<div class="form-group">
<input type="text" name="username" placeholder="username" class="form-control">
</div>
<div class="form-group">
<input type="password" name="password" placeholder="password" class="form-control">
</div>
<!-- <div align="center"> -->
{% if form.errors %}
<!-- <p style="color: red; font-style: italic;">Your username or email is does not match.</p> -->
{{form.errors}}
{% endif %}
<!-- </div> -->
<div class="loginbtndiv" align="center">
<input type="submit" class="btn btn-warning btn-lg loginbtn" value="LOGIN">
</div>
<input type="hidden" name="next" value="{{ next }}">
</form>
</div>
</div>
<div>
</div>
</div>
{% endblock %}

Numbered loop in Jinja

I'm trying to make a quiz app using Django, Jinja2 and PostgreSQL. I want to number the questions but I don't know how to because python doesn't use a counter in for loops (e.g. for exercise in exercises - no for loop here)
I've tried to change the for loop
(for exercise in exercises)
so it has a counter
(for x in myrange)
and defining myrange in views.py to be a range(1, len(exercitii+1))
but after that I didn't know how to access the elements inside the Jinja template.
I tried to access the exercises with
{exercitii.x-1.intrebare}}
but it didn't work.
html template
{% extends 'base.html' %}
{% load static %}
{% block content %}
</div>
<div id="middle-section" class="container-fluid container-fluid-margin">
<div class="content-quiz">
<form action="{% url 'exercitiu' lectii.id %}" method="POST" id="quiz">
{% for exercitiu in exercitii %}
<div class="row content-block">
<div class="col-lg-10 text-card">
{% csrf_token %}
<div class="card card-custom">
<div class="card-body">
<h5 class="card-title">{{exercitiu.id}} - {{exercitiu.intrebare}}</h5>
<div class="card-text">
<input type="radio" name="question-{{exercitiu.id}}-answers" id="question-{{exercitiu.id}}-answers-A" value="A" />
<label for="question-{{exercitiu.id}}-answers-A">A) {{exercitiu.variante.0}} </label>
</div>
<div class="card-text">
<input type="radio" name="question-{{exercitiu.id}}-answers" id="question-{{exercitiu.id}}-answers-B" value="B" />
<label for="question-{{exercitiu.id}}-answers-B">B) {{exercitiu.variante.1}} </label>
</div>
<div class="card-text">
<input type="radio" name="question-{{exercitiu.id}}-answers" id="question-{{exercitiu.id}}-answers-C" value="C" />
<label for="question-{{exercitiu.id}}-answers-C">C) {{exercitiu.variante.2}} </label>
</div>
<div class="card-text">
<input type="radio" name="question-{{exercitiu.id}}-answers" id="question-{{exercitiu.id}}-answers-D" value="D" />
<label for="question-{{exercitiu.id}}-answers-D">D) {{exercitiu.variante.3}} </label>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
<input type="submit" value="Trimite" class="btn btn-secondary btn-block btn-login-custom" style="margin-bottom: 2rem;">
</div>
</div>
{% endblock %}
views.py
from django.shortcuts import render
from django.shortcuts import get_object_or_404
from .models import Exercises
from .models import Lectie
def exercitii(req):
lectii = Lectie.objects.all().order_by("id")
context = {
'lectii': lectii
}
return render(req, '../templates/pagini/exercitii-selector.html', context)
def exercitiu(req, lectie_id):
lectii = get_object_or_404(Lectie, pk=lectie_id)
exercitiiObj = Exercises.objects.filter(idLectie=lectie_id)
context = {
'lectii': lectii,
'exercitii': exercitiiObj
}
return render(req, '../templates/pagini/exercitii.html', context)
(lectie = lesson, lectii = lessons, exercitii = exercises)
So how can I number the questions from exercitiiObj in the template? Right now the output is the exercise ID from the DB which isn't helpful at all.
Thanks.
If I got your question correctly, you want to get the iteration number of the for loop in jinja.
Jinja provides a very convenient loop variable, it has a property called loop.counter which is 1-indexed, and loop.counter0 which is 0-indexed. View Docs
And if you're using DjangoTemplate, then those become forloop.counter0 and forloop.counter. View Docs

Add Bootstrap to Inbulit Login View Django

I am using the default view for logging the users.So I have not made any modelForm for it.So I am not able to provide any bootstrap class to the input fields i.e username and password. So my login form is looking ugly.Is there anyway. I want to add bootstrap class form-control to the input fields username and password.
Following is my HTML and URL snippets. All functions and classes used have their modules imported.
urls.py
url(r'^login/$', login, {'template_name': 'app/login.html'}),
login.html
<form class="form-signin" method="post"><span class="reauth-email"> </span>
{% csrf_token %}
<!--{{form.as_p}}-->
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }} {{ field }}
{% if field.help_text %}
<p class="help">{{ field.help_text|safe }}</p>
{% endif %}
</div>
{% endfor %}
<!--<input class="form-control" type="email" required="" placeholder="Email address" autofocus="" id="inputEmail">-->
<!--<input class="form-control" type="password" required="" placeholder="Password" id="inputPassword">-->
<div class="checkbox">
<div class="checkbox">
<label><input type="checkbox">Remember me</label>
</div>
</div>
<button class="btn btn-primary btn-block btn-lg btn-signin" type="submit">Sign in</button>
</form>
change your login template to this
you can modify it
<div class="center-block" id="login" style="width: 40%;">
<form class="form-horizontal form" name="LoginForm" method="post">
{% csrf_token %}
{% if next %}
<input type="hidden" name="next" value="{{ next }}" />
{% endif %}
<div class="control-group">
<label class="control-label" for="username">Username</label>
<div class="controls">
<input class="form-control" type="text" id="username" name="username" placeholder="Username">
</div>
</div>
<div class="control-group">
<label class="control-label" for="password">Password</label>
<div class="controls">
<input class="form-control" type="password" name="password" id="password" placeholder="Password">
</div>
</div><br>
<div class="control-group">
<div class="controls">
<button type="submit" class="btn btn-success">Login</button> or sign up
</div>
</div>
</form>
</div>
If you want to add a CSS-class, you can write a custom template filter
First, read how to make a custom template filter
https://docs.djangoproject.com/en/1.11/howto/custom-template-tags/#writing-custom-template-filters
You'll have write here
my_app/
__init__.py
models.py
templatetags/
__init__.py
my_app_extra_filters.py # <-----------------
views.py
smth like this
my_app_extra_filters.py
from django import template
register = template.Library()
#register.filter
def add_class(modelform_input, css_class):
return modelform_input.as_widget(attrs={'class': css_class})
*if you want to know about as_widget() method, used above:
https://docs.djangoproject.com/en/1.11/ref/forms/api/#django.forms.BoundField.as_widget
then use it in the template
{% load my_app_extra_filters %}
...
{{ field.errors }}
{{ field.label_tag }}
{{ field|add_class:'bootstrap_class_name' }}
all you need is add this codes to your loginform in form.py
class AuthenticationForm(AuthenticationForm):
.
.
.
def __init__(self, *args, **kwargs):
super(UserCreationForm, self).__init__(*args, **kwargs)
for fieldname in ['username', 'password1', 'password2',]:
self.fields[fieldname].widget.attrs = {'class':'form-control'}

How to get textbox value in views.py django

I am trying to get the value of a textbox from views.py but its not working for some reason.
Below is my code
base.html
<form method="POST" role="form" >
{% csrf_token %}
<div class="tab-content">
<div class="tab-pane active" role="tabpanel" id="step1">
<div class="mobile-grids">
<div class="mobile-left text-center">
<img src="{% static 'images/mobile.png' %}" alt="" />
</div>
<div class="mobile-right">
<h4>Enter your mobile number</h4>
<!-- <label>+91</label><input type="text" name="mobile_number" class="mobile-text" value="asdfasd" onfocus="this.value = '';" onblur="if (this.value == '') {this.value = '';}" required=""> -->
<label>+91</label><input type="text" name="mobile_number" class="mobile-text" value="" >
</div>
</div>
<ul class="list-inline pull-right">
<li><button type="button" class="mob-btn btn btn-primary btn-info-full" data-dismiss="modal">Finish</button></li>
</ul>
</div>
<div class="clearfix"></div>
</div>
</form>
views.py
def home(request):
mobile_number = request.POST.get('mobile_number')
print(mobile_number)
return render(request,"home.html", {'mobile_number': mobile_number})
I am getting None when I try to get the value of textbox mobile_number.
How can I get the correct value?
You are missing a submit-button (<input type="submit" value="submit"/>) from the from.
To see the value on the form after submitting it, change value=""on the mobile_number -row, to value="{{ mobile_number }}".
My solution
1. You have to set action in form field as your functon in view.py
<form class="forms-sample" name="form" action="{% url "update_size" %}" method="post">
You have make button type as submit.
<button type="Submit" value="Submit" name="Submit" class="btn btn-primary">
url.py
path('updatesize/', views.updatesize, name='update_size')
View.py
def updatesize(request):
if (request.method == 'POST'):
temp = request.POST.get('size_name')
print("==================form================",temp)
return redirect("/collection.html")

Categories