Django can't process html form data - python

I have a simple Django site and I want to pass data from the first box, and return that value plus 5 to the second form box on the page. I later plan on doing math with that first value but this will get me started. I am having a lot of trouble retrieving the form data. I know I need to create a function in my views.py file to process the form, and I need to put something in URLs.py to retrieve the form data. I have tried everything in tutorials, etc, but can't figure it out.
My html template is a simple page that has a form with two fields and a submit button. Django runserver pulls up the html page just fine. Here is my code:
Views.py
from django.shortcuts import render
from django.http import HttpResponse
from django.template import loader
from django import forms
def index(request):
return render(request, 'brew/index.html')
#Here I want a function that will return my form field name="input",
#and return that value plus 5 to the form laveled name="output".
#I will later us my model to do math on this, but I cant get
#this first part working
urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index, name='index'),
]
Here is my html template, index.html:
<html>
<head>
<title>Gravity Calculator</title>
</head>
<body>
<h1>Gravity Calculator</h1>
<p>Enter the gravity below:</p>
<form action="/sendform/" method = "post">
Enter Input: <br>
<input type="text" name="input"><br>
<br>
Your gravity is: <br>
<input type="text" name="output" readonly><br>
<br>
<input type="submit" name="submit" >
</form>
</body>
</html>

You will need to populate the result to context variable which the template can access.
view:
def index(request):
ctx = {}
if request.method == 'POST' and 'input' in request.POST:
ctx['result'] = int(request.POST.get('input', 0)) + 5
return render(request, 'brew/index.html', ctx)
then in your template:
<html>
<head>
<title>Gravity Calculator</title>
</head>
<body>
<h1>Gravity Calculator</h1>
<p>Enter the gravity below:</p>
<form action="/sendform/" method = "post">
Enter Input: <br>
<input type="text" name="input"><br>
<br>
Your gravity is: <br>
<input type="text" name="output" value="{{ result }}" readonly><br>
<br>
<input type="submit" name="submit" >
</form>
</body>
</html>
Looks like you are quite new at Django, I recommend:
use method based views, until you are comfortable with it, then
start using class based views, advantage being code reusability, but ultimately class based views spits out view methods, a good
reference site is ccbv.co.uk
using form class

Related

How to save output into single drop-down with django

I have a scraper that scraper data on cruises, I am grabbing the title of the cruise. My aim was to output these results into a single drop down menu so I can select one of these from the drop-down. However, it instead produces multiple input options and only a single title in the drop down. I.E.
My script:
models.py:
from django.db import models
class Cruises(models.Model):
title = models.TextField(max_length=200)
views.py:
from django.shortcuts import render
from .models import Cruises
def basic(request):
long_list = Cruises.objects.values('title')
return render(request, 'cruise_control/basic.html', context = {'long_list':long_list})
basic.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Cruises</title>
</head>
<body>
<h1> Cruise Control </h1>
{% for lng_l in long_list %}
<form action="/action_page.php">
<label for='destination'>Destination</label>
<input type="text" list="destination" />
<datalist id="destination">
<option>{{lng_l.title}}</option>
</datalist>
<!label for="cruisetime">Departure date</label>
<!input type="date" id="cruisetime" name="cruisetime" min={{dep_l.departureDate}}>
<!input type="submit">
</form>
{% endfor %}
</body>
</html>
Your class Cruises contains only one title. As for the loops in the template, you are looping the forms. Whereas you want one in a form with many options.
I think you should be interested in a many-to-many relationship. Then you will be able to assign multiple options to a particular object.
Also you should see documentation about forms.

How do I get user input from search bar to display in a page? Django

Django is very challenging and I still need to get used to the code and currently, I just want the search bar to display every time a user input a text and it will display like a title I really don't how to interpret the code to tell that every time the user inputs in the search bar, It is supposed to display the user input on a page like a title.
Example: user input in the search bar: cat and it displays cat title
Display on the current page:
Result search: "Cat"
HTML Code
<!-- Search Bar -->
<form action="{% url 'enc:search' %}" method="GET">
{% csrf_token %}
<input class="search" type="text" name="q" placeholder="Search">
</form>
In my views.py I only write this code and I don't know what to write it.
views.py
def search (request):
title = request.GET.get("q", "")
urls.py
urlpatterns = [
path("", views.index, name="index"),
path("search/", views.search, name="search"),
Right now just a simple display from the search bar input later I will code it in a data search where there is some file to integrate the search but right now I really need some help my brain is cracking. It's kinda sad I mean I know it be a simple code but I don't know why I can't figure it out.
please do help me if you have tips on how to be better on Django and python too it be much help for me and thank you for your time I really appreciate it very much.
searchpage.html :
<!-- Search Bar -->
<form action="{% url 'enc:search' %}" method="POST">
{% csrf_token %}
<input class="search" type="text" name="q" placeholder="Search">
<input type="submit" value="Submit">
</form>
views.py:
from django.shortcuts import render
def search (request):
#defines what happens when there is a POST request
if request.method == "POST":
title = request.POST.get("q")
return render(request,'new_template.html', { 'title' : title })
#defines what happens when there is a GET request
else:
return render(request,'searchpage.html')
new_template.html:
<!DOCTYPE html>
{% load static %}
<html>
<head>
<title>search term</title>
</head>
<body>
<h1> {{ title }} </h1>
</body>
</html>

Django can't search "method not allowed"

im new to django and im currently doing a website for my friend. he wants me to make a system where the users can search the database and the website gives the relevent items according to their serial number.
i followed a tutorial from the following site: https://learndjango.com/tutorials/django-search-tutorial to figure out how to do db searchs which helped a lot, but im still having a problem: my search bar works, and the result page also works but it only works when i manually type the query on the searchbar myself (e.x. results/?q=number1). However when i search using the input bar and the submit button it sends me to /results/ page and the page gives this:
This page isn’t working
If the problem continues, contact the site owner.
HTTP ERROR 405
-when i open up pycharm to see the error in terminal it says:
Method Not Allowed (POST): /result/
Method Not Allowed: /result/
[27/Oct/2020 20:06:02] "POST /result/ HTTP/1.1" 405 0
here are my codes(python3.7,pycharm) websites/urls:
from . import views
from django.urls import path
from django.contrib.auth import views as auth_views
urlpatterns = [
path('register/',views.UserFormView.as_view(), name='register'),
path('login/', auth_views.LoginView.as_view(), name='login'),
path('', views.IndexViews.as_view(), name='index'),
path('scan/', views.ScanView.as_view(), name='scan'),
path('result/', views.SearchResultsView.as_view(), name='result'),
]
websites/views:
class IndexViews(generic.ListView):
template_name = "websites/index.html"
context_object_name = "object_list"
def get_queryset(self):
return Website.objects.all()
class ScanView(TemplateView):
form_class = SerialFrom
template_name = 'websites/scan.html'
class SearchResultsView(ListView):
model = SerialNumber
template_name = 'websites/result.html'
def get_queryset(self): # new
query = self.request.GET.get('q')
context = self.get_context_data(object=self.object)
object_list = SerialNumber.objects.filter(
Q(number__iexact=query)
)
return object_list
scan.html:
{% extends 'websites/base.html' %}
{% block albums_active %}active{% endblock %}
{% block body %}
<head>
<meta charset="UTF-8">
<title>Scan</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<form class="box" action="{% url 'result' %}" method="POST">
<h1>Product Check</h1>
<p> Please enter the serial id of your product to check it.</p>
{% csrf_token %}
<input type="text" name="q" placeholder="Serial Number">
<input type="submit" name="q" placeholder="Check">
</form>
</body>
{% endblock %}
thank you for taking your time and reading, please help me i really need to do this.
A ListView [Django-doc] by default does not implement a handler for a POST request. Searching is normally done through a GET request, so you should use:
<form class="box" action="{% url 'result' %}" method="GET">
<h1>Product Check</h1>
<p> Please enter the serial id of your product to check it.</p>
<input type="text" name="q" placeholder="Serial Number">
<input type="submit" placeholder="Check">
</form>
Furthermore the <input type="submit"> should not have a name="q" attribute.
As #Melvyn says, you can also alter the type to type="search" [mozilla] for the text box:
<form class="box" action="{% url 'result' %}" method="GET">
<h1>Product Check</h1>
<p> Please enter the serial id of your product to check it.</p>
<input type="search" name="q" placeholder="Serial Number">
<input type="submit" placeholder="Check">
</form>

Django page not saving data correctly

I have a form in a HTML page that I'm using for a Django project. This form takes the input from the user and sends it to a page which should save it to the database, but right now its not doing do. Here is the code:
<!DOCTYPE html>
<html>
<body>
<h2>Create product here</h2>
<div>
<form id="new_user_form" method="post" action="user/create"}>
{% csrf_token %}
<div>
<label for="name" > Name:<br></label>
<input type="text" id="name"/>
</div>
<br/>
<div>
<label for="description"> description:<br></label>
<input type="text" id="description"/>
</div>
<div>
<label for="price" > price:<br></label>
<input type="text" id="price"/>
</div>
<div>
<input type="submit" value="submit"/>
</div>
</div>
</form>
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</html>
My urls.py file:
from django.contrib import admin
from django.urls import path
from django.conf.urls import include, url
from testapp import views
admin.autodiscover()
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.index),
path('user/create', views.create_user, name='create_user')
]
The views.py file:
from django.shortcuts import render
from testapp.models import User
from django.http import HttpResponse
def index(request):
return render(request, 'index.html')
def create_user(request):
if request.method == 'POST':
name = request.POST.get('name')
description = request.POST.get('description')
price = request.POST.get('price')
newUser = User(
name = name,
description = description,
price = price
)
newUser.save()
return HttpResponse('')
And the models.py file:
from django.db import models
# Create your models here.
class User(models.Model):
name = models.CharField(max_length = 32, null = True)
description = models.TextField(null = True)
price = models.CharField(max_length = 128, null = True)
Now the problem is when the form data gets sent to the function create_user, it should take the data and create a object with that data and save it to the database. The database is set up correctly as when I use the Django shell to test it, users are created and saved. However, through the form and the python, something is going wrong here and I'm not sure why. Can someone help me out here?
You need to put the name in the inputs html tags
<input type="text" id="name" name="name"/>
<input type="text" id="description" name="description"/>
<input type="text" id="price" name="price"/>

Django: Use text box data and write that text in a file

I am super new to Django and web development. Right now my objective is to create a google like interface and take the text from search box and write it to a file (in other words just want to access text data in the search box). I have created a search page like below
search.html
{% extends "header.html" %}
{% block content %}
<div style="display: flex; justify-content: center;">
<img src="/static/images/logo.jpg" class="responsive-img" style='max-height:300px;' alt="face" >
</div>
<form method="get" action="">
{% csrf_token %}
<div style="display: flex; justify-content: center;">
<input type="text" name="query" placeholder="Search here..." required size="70" >
<button type="submit">Go!</button>
</div>
<button type="submit">Search</button>
</form>
{% endblock %}
views.py
from django.shortcuts import render
def index(request):
return render(request, 'search.html')
urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index, name='index')
]
Please give me a hint/example of how to go forward from here ? Thanks.
Your search field looks like this:
<input type="text" name="query">
The name of the input is query. Since it's a GET form, when you submit it, you must have noticed, the url looks something like this:
/?query=<value of the input>
The part after ? is called querystring. For every request, Django maintains a dictionary of the querystring. The request object has a dictionary called GET for GET requests. If you make a POST request, Django will save the form data in a dict called POST.
To access the value of the request querystring in Django, you can do this:
query = request.GET.get('query')
If it's a POST request, you'd do the same but use the POST dictionary this time:
some_value = request.POST.get('some_key')
Full docs on this can be found at - Request and response objects.
This should do it
views.py
def index(request):
query = request.GET.get('query')
# do a check here to make sure search_term exists before attempting write
with open('/path/to/file', 'rw') as f:
f.write(query)
return render(request, 'search.html')

Categories