Submitting data from a form to django view - python

When I open the html file it displays as expected and when I enter data in the text box and submit, It redirects me to localhost/myapp/output/ but why is the data I enter in the text box not submitted for example like localhost/myapp/output/data_I_submitted
My basic html file:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>db app</title>
</head>
<body>
{% csrf_token %}
<form action="output/" method="post" name="Input">
Data : <input type="text" name="text">
<input type="submit" value="submit">
</form>
</body>
</html>
In my app.urls file:
urlpatterns = patterns('',
url(r'^$',views.index),
url(r'^output/(?P<text>\w+)/$',views.return_data)
)
Finally the view:
def return_data(request,text):
return HttpResponse('entered text ' + text)

If your goal is only getting the text on the form:
change your view to
def return_data(request):
return HttpResponse('entered text:' + request.POST['text'])
edit your urls
urlpatterns = patterns('',
url(r'^$', views.index),
url(r'^output/$', views.return_data)
)
and your template
<form action="output/" method="post">
{% csrf_token %}
...
</form>

you'd better review data submitting in forms.
with two methods you can submit forms data with your request to the forms action attribute:
GET: like http://www.google.com/?q=keyword+to+search
you can access the "keyword+to+search" by:
request.GET['q']
#or better is:
request.GET.get('q', None)
the text arguement is not passed to url pattern. so not accessible in this way
POST:
in this method the data is not in request url.
so to access the forms data submittin by POST method
try this
request.POST['text'] (
#or better is:
request.POST.get('text', None)
but it is highly recommended to use Django forms instead of direct accessing from request.POST or request.GET
so check this: https://docs.djangoproject.com/en/dev/topics/forms/

Related

Django stops updating data to mysql after page refresh

I'm fairly new to using the django framework and recently I made a system with it where it submits data to mysql db through a html form. I got it working eventually and everything seemed quite fine, though I noticed a bug where if I refresh the page django stops sending data to mysql, has this ever happened to anyone?
Stuff for reference:
views.py
from django.shortcuts import render
from websiteDB.models import dbInsert
from django.contrib import messages
def insertToDB(request):
if request.method == "POST":
if request.POST.get('uname') and request.POST.get('email') and request.POST.get('message'):
post = dbInsert()
post.uname = request.POST.get('uname')
post.email = request.POST.get('email')
post.message = request.POST.get('message')
post.save()
messages.success(request, "Message sent successfully.")
return render(request, "contact.html")
else:
return render(request, "contact.html")
models.py
from django.db import models
class dbInsert(models.Model):
uname = models.CharField(max_length=100)
email = models.EmailField()
message = models.TextField()
class Meta:
db_table = "contactrequest"
urls.py
"""
websiteDB URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/4.0/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from django.views.generic import TemplateView
from . import views
from . import index
urlpatterns = [
#path('admin/', admin.site.urls),
path('homepage', index.page_home, name= 'hpage'),
path('', views.insertToDB),
path('contactpage', index.contact_page, name= 'cpage')
]
contact.html
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght#200&display=swap" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="{% static 'css/css/styles.css' %}">
<title>Document</title>
</head>
<body style="background-color: rgb(74, 36, 110);">
<script src="{% static 'js/main.js' %}"></script>
<div class="top-nav">
HOME
PRODUCTS
CONTACT
ABOUT
COMMUNITY
</div>
<div class="div-align">
<h2>Contact</h2>
<p>Reach us for questions/concerns through the form below.</p>
</div>
<form class="fontmaker" method="post">
{% csrf_token %}
<label for="Username">Username:</label><br>
<input type="text" id="Username" name="uname" required><br>
<label for="E-mail">E-mail:</label><br>
<input type="text" id="Email" name="email" required>
<label for="Reason" class="margin">Message:</label>
<textarea id="Reason" name="message" rows="10" cols="60" required>Type your reason of contact here.</textarea>
<input type="submit" value="Submit" class="rounded-corners" id="submitBtn">
{% if messages %}
{% for message in messages %}
{{message}}
{% endfor %}
{% endif %}
</form>
</body>
</html>
There are no errors in terminal, and the button click also properly sends a POST req:
Terminal output
I'm also new to posting on stackoverflow, tell me if there's something else to improve on in the future when posting.
index.py
from django.http import HttpResponse
from django.shortcuts import render
def page_home(request):
return render(request, 'index.html')
def contact_page(request):
return render(request, 'contact.html')
Thanks in advance.
If you render the contactpage/ URL, then if you submit the form, you will submit it to the contact view, but that view does not handle the data, nor does it create any entry. You must make sure that you post the form to the insertToDB view. You can do this by giving the view a name:
urlpatterns = [
# …,
path('', views.insertToDB, name='insertToDB'),
# …
]
and then specify the endpoint in the form:
<form class="fontmaker" method="post" action="{% insertToDB %}">
<!-- … -->
</form>
In case of a successful POST request, you should also redirect, for example with:
from django.shortcuts import redirect
def insertToDB(request):
if request.method == 'POST':
if request.POST.get('uname') and request.POST.get('email') and request.POST.get('message'):
post = dbInsert.objects.create(
uname = request.POST['uname'],
email = request.POST['email'],
message = request.POST['message']
)
messages.success(request, 'Message sent successfully.')
return redirect('cpage')
return render(request, 'contact.html')
else:
return render(request, 'contact.html')
I would advise to work with Django forms [Django-doc], for example a modelform [Django-doc] to validate and clean form input and remove a lot of boilerplate code.

Django malformed views.py or urls.py (redactor app)

I’m trying to write a web app which accepts a website visitor’s input which is a 12 digit “Chuckee Cheese” membership card number and then redacts the first 8 digits and presents the redacted number. I’ve got my template written and the basic logic inside my app’s views.py. The problem now is that after the user enters his or her card number, Django is not processing the user input properly. Like, the redacted number is not being presented and served in the template as intended.
Here is a pic on imgur showing my website running on my dev server now. As you can see in that pic, in the web address bar Django receives the ‘ccEntry’ GET Request with ‘123456789102’ as user input. So I guess that kind of works. But below the two h1 elements (in lime green), Django should show the card number ‘123456789102’ as well as the redacted card number ‘xxxx xxxx 9102’ but instead it’s blank. What is wrong here? As far as I can tell, I believe the problem involves either the first two functions inside my redactors views.py or the way my app’s urls.py is arranged.
Here is my views.py :
from django.shortcuts import render
# Create your views here.
def redactors(request):
return render(request, 'alls/landings.html')
def home(request):
if 'ccEntry' in request.GET:
number = request.GET['ccEntry']
redacted_num = 'xxxx xxxx {}'.format(number[-4:])
return render(request, 'alls/landings.html', {'number':number, 'redacted_num':redacted_num})
else:
return render(request, 'alls/landings.html')
def results(request):
return render(request, 'alls/landings.html')
Here is my app’s urls.py:
from django.urls import path, include
from . import views
urlpatterns = [
path('home', views.home, name='home'),
path('results', views.results, name='results'),
]
Those are the two scripts where I believe the problem is.
For what it is worth, here are some other related configuration files and scripts that are in play:
Lightly abbreviated alls/landings.html template:
{% load static %}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="description" content="The HTML5 Herald">
<meta name="robots" content="noindex,nofollow" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Custom -->
<link rel="stylesheet" href="{% static 'css/style.css' %}">
</head>
<body>
{% block content %}
<div class="card-processor">
<h3>Enter your fake Chuckee Cheese Neptune membership card number!</h3>
<form action="{% url 'posts' %}" method="get">
<div>
<label for="password">Enter Card Number:</label>
<input type="text" id="password" name="ccEntry" pattern="[0-9]{12}" maxlength="12"/>
<div class="requirements">Must be a 12 digit number and no letters. </div>
<input type="submit" value="Redact!" class="button"/>
</div>
</form>
<h1>Here is your fake Chuckee Cheese Neptune memnership card number!</h1>
<h3 style="color:lime">This was the original number that you entered:</h3>
<div class="field">{{ number }}</div>
<h3 style="color:lime">Here it is redacted:</h3>
<div class="field">{{ redacted_num }}</div>
<div class="field"><strong>Again? Click here!</strong></div>
</div> <!--- END card-processor -->
<div class="post-content">
{% for post in posts %}
<h1> Blog post title: <em>{{ post.title }}</strong></em>
<h4>Publication Date: {{ post.pub_date_preference }}</h4>
<img src="{{ post.image.url }}" class="authors-pic" style="" />
<!-- Body text should go here : -->
<p>{{ post.body|safe }}</p>
{% endfor %}
{% endblock %}
</body>
</html>
Parent urls.py router:
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('posts.urls')),
path('', include('redactors.urls')),
path('', include('counters.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
I believe those are all the relevant files in play. However in case the problem is elsewhere, if you want to see the rest of my source code, here is a static snapshot tagged as v.0.7.0 on my GitHub.
It's also worth noting that I'm not getting a trace back and my server is not crashing so I don't have many leads in terms of searching on Google for other developers resolving similar or related issues.
It seems like the 'form' in landings.html is being submitted to the path with name "posts", But there is no path with this name in your app's urls.py.
Use this <form action="{% url 'home' %}" method="get"> instead of <form action="{% url 'posts' %}" method="get">.

How do I get the values from input text fields from my custom form through the request: Django 3.0?

So, I've been trying hard, getting values from input fields in my custom form.
I have a url that corresponds to the form and that form redirects it to the same form again.
The view of the form url checks whether the request method is Post. If it is, then I declare a variable equal to request.POST, I then assigned those values to my model- item_description(). Here is the code of the views.py:
def addItem(request):
if request.method == "POST":
data = request.POST
print(data.__dict__)
item_description(item_name=data.item_name, item_number=data.item_number, item_quantity=data.item_quantity)
else:
HttpResponse("Something went wrong!")
return render(request, 'ims/addItemForm.html')
HTML form:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>IMS| Add Item</title>
</head>
<body>
<form action="{% url 'Item-addition' %}" method="post">
{% csrf_token %}
<input type="text" name="item_name" placeholder="Enter Item Name">
<input type="text" name="item_number" placeholder="Enter Item Number">
<input type="text" name="item_quantity" placeholder="Enter Item Quantity">
<button type="submit" name="add" value="add">Add Item</button>
</form>
See items
</body>
</html>
urls.py:
from django.urls import path
from . import views
urlpatterns = [
path('add_item', views.addItem, name='Item-addition'),
path('items', views.itemsList, name='Items-list'),
]
models.py:
from django.db import models
class item_description(models.Model):
item_name = models.CharField(max_length=200)
item_number = models.CharField(max_length=200)
item_quantity = models.CharField(max_length=200)
def __str__(self):
return self.item_name
Also, I printed out the request which is a dictionary, but it was not having any of the values. Here is the printed request dictionary: {'_encoding': 'utf-8', '_mutable': False}.
Here is the error which I am getting:
File "/home/zaid/inventoryManagement/venv/src/ims/views.py", line 13, in addItem
item_description(item_name=data.item_name, item_number=data.item_number, item_quantity=data.item_quantity)
AttributeError: 'QueryDict' object has no attribute 'item_name'
Please help me getting values from the input fields.
Your mistakes:
item_description(item_name=data.item_name, item_number=data.item_number, item_quantity=data.item_quantity)
data is a QueryDict, so you must access the data in it using data['item_name'] or data.get('item_name') as you would for a regular dict.
item_description(...) doesn't actually do anything. It does not save anything to the database. To save to the database, you must use item_description.objects.create(...).
Other problems with your code:
you render the form fields on your own
you extract the POST data on your own
you attempt to save to the database on your own
you are missing input validation (what if some required values are missing? e.g. what if item_name is not submitted?)
you did not provide a suitable error message as feedback to the user if he/she enters inappropriate values (e.g. a string of length 201).
Django's ModelForm is able to handle all of these issues, so please use ModelForm instead.
If models.py is this:
from django.db import models
class ItemDescription(models.Model):
item_name = models.CharField(max_length=200)
item_number = models.CharField(max_length=200)
item_quantity = models.CharField(max_length=200)
def __str__(self):
return self.item_name
Then, create a ModelForm in forms.py:
from django import forms
from .models import ItemDescription
class ItemDescriptioneForm(forms.ModelForm):
class Meta:
model = ItemDescription
fields = ['item_name', 'item_number', 'item_quantity']
In your views.py, use the ModelForm you just created:
from django.shortcuts import render, redirect
from .forms import ItemDescriptionForm
def addItem(request):
if request.method == 'POST':
form = ItemDescriptionForm(request.POST)
if form.is_valid():
form.save()
return redirect('Items-list')
else:
form = ItemDescriptionForm()
return render(request, 'ims/addItemForm.html', {
'form': form,
})
Show the form in your template:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Add Item</title>
</head>
<body>
<form action="" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" />
</form>
</body>
</html>

Google Search using python

I get data from input. When I click to search button I need to open webbrowser page and see my input data in google. How can I do that? Many thanks.
This is my code:
views.py:
from django.http import HttpResponse
from django.shortcuts import render
def index(request):
if request.method == 'GET':
return render(request, 'index.html', context={})
# Handles the search once the submit button in the form is pressed
# which sends a "POST" request
if request.method == 'POST':
# Get the input data from the POST request
search_query = request.POST.get('search', None)
# Validate input data
if search_query and search_query != "":
return HttpResponse(search_query)
try:
from googlesearch import search
except ImportError:
print("No module named 'google' found")
for j in search(search_query, tld="co.in", num=10, stop=1, pause=2):
print(j)
else:
return HttpResponse('Invalid input.')
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<form method="POST">
{% csrf_token %}
<input type="text" name="search" placeholder="some text"><br>
<button class="button" name="submit" type="submit">Search</button>
</form>
</body>
</html>
urls.py
from django.urls import path
from firstapp import views
urlpatterns = [
path('', views.index, name='home')
]
All files are in hello folder. My app namely firstapp path: C:\Users\user\Desktop\hello\firstapp
index.html path is:
C:\Users\user\Desktop\hello\firstapp\templates
In order to redirect to google you need to have your search textfield to use a parameter called q. Here is an index.html file that would work:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<form action="https://google.com" method="GET">
{% csrf_token %}
<input type="text" name="q" placeholder="some text"><br>
<input type="submit" name="submit" value="Search">
</form>
</body>
</html>

Not able to redirect to view after login

I am trying to create a redirect when the user logs in. For example when user tries to access a link to create blog post he is prompted to log in , and after he gets logged in he is redirected to the page to create the post. I am extracting the next parameter from the url.
blog.urls
from django.conf.urls import url
from blog import views
urlpatterns=[
url(r'^$',views.index,name="index"),
url(r'^signup/$',views.signup_view,name="signup_view"),
url(r'^login/$',views.login_view,name="login_view"),
url(r'^create-post/$',views.create_blog,name="create_post"),
url(r'^logout/$',views.logout_view,name="logout_view"),
]
blog.views:
def login_view(request):
if request.method == 'POST':
form=LoginForm(request.POST)
if form.is_valid():
username=form.cleaned_data['username']
password=form.cleaned_data['password']
user=authenticate(username=username,password=password)
if user is not None:
if user.is_active:
login(request,user)
go_to=request.GET.get('next','/')
print go_to
return HttpResponseRedirect(go_to)
else:
return HttpResponse("Not active")
else:
return HttpResponse("User doesn't exist")
else:
form=LoginForm()
return render(request,'blog/login.html',{'form':form})
and blog/login.html
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Login</title>
</head>
<body>
<form method="POST" action="/login/">
{% csrf_token %}
<table>
{{form.as_table}}
</table>
<button type="submit">Submit</button>
</form>
</body>
</html>
Whenever I login it shows the next parameter as '/' while there is "next=/create-blog/" in the url. Please suggest any solution.
you need:
action="/login/{% if request.GET.next %}?next={{ request.GET.next }}{% endif %}"
If the value of {{ request.GET.next }} includes parameters, e.g. http://example.com/?var1=abc&var2=def, then use URL encoding {{ request.GET.net | urlencode }}.

Categories

Resources