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

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')

Related

Django and HTMX active search issue

I'm trying to make an active search with HTMX in Django, and it's working, but happens that if I delete the search terms in the form the entire page is rendered twice and can`t fix it.
This is ok:
But this happens if I delete the text introduced in the form:
view.py
class SearchView(View):
#staticmethod
def get(request):
search_term = request.GET.get('search', None)
if search_term:
roads = Road.objects.filter(name__contains=search_term).all()[:100]
template = 'search_results.html'
else:
roads = []
template = 'pkes/search.html'
return render(request=request,
template_name=template,
context={
'roads': roads,
})
search.html
{% extends "pkes/base.html" %}
{% block content %}
<form action="/action_page.php">
<label for="search">Carretera</label>
<input class="input"
name="search"
type="search"
placeholder="Ej: EX-118"
hx-get="/search"
hx-trigger="keyup changed delay:500ms, search"
hx-target="#search-results"
hx-swap="innerHTML"/>
<label for="kilometro">Kilómetro</label>
<input class="input" name="kilometro">
<input type="submit" value="Enviar">
</form>
<div id="search-results">
{% include "search_results.html" %}
</div>
{% endblock %}
search_results.html
{% for road in roads %}
<div>
{{ road.name }}
</div>
{% endfor %}
Thanks!!!
Django 4.1.6, Python 3.11.1, HTMX 1.8.5
Reference: rockandnull.com
You have two types of requests: the regular one, where the client expects a full rendered page, and the HTMX one, where the client expects just an HTML fragment. You have to identify the type of a request in a view function and return full or partial rendered template to the client. Currently you try to guess the type of the request based on the length of the search term. So when the search term is cleared you return a full page instead of just a fragment causing the double rendering issue.
In this modified view function we have a new variable is_htmx that identify the request type. We set the template (full or fragment) based on this. Furthermore we execute a search query based on the search term or just return an empty list.
class SearchView(View):
#staticmethod
def get(request):
search_term = request.GET.get('search', None)
is_htmx = self.request.headers.get('HX-Request') == 'true'
template = 'search_results.html' if is_htmx else 'pkes/search.html'
roads = Road.objects.filter(name__contains=search_term).all()[:100] if search_term else []
return render(request=request,
template_name=template,
context={
'roads': roads,
})
You can also use the Django-HTMX package, so you have a request.htmx attribute set by a middleware that identifies the type of the request.

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>

Reverse for 'customerdel' with arguments '('',)' not found.1 pattern(s) tried: ['dashboard/records/customerdel/(?P<pk>[0-9]+)$']

I am trying to delete an object from database using simple html button. Also, trying to implement "are you sure" message? BUt I am getting this error everytime and I am not able to crack.
This is my view function.
def customerdel(request,pk):
objs = Customer.objects.filter(id=pk)
if request.method == 'POST':
objs.delete()
# messages.success(request, 'Successfully deleted')
return render(request,'records.html')
else:
content ={
'items':Customer.objects.all
}
return render(request,'delete.html', content)
This is record.html page
<h1>Record's page</h1>
{% for abc in Customerdata %}
{{abc.name}}
{{abc.pk}}
<form >
<button class="btn btn-danger btn-sm">
Delete</button>
</form>
{% endfor %}
This is delete.html page
<h1>Welcome to Delete page</h1>
<p>Are you sure want to del {{items.name}} ??</p>
<form action="{% url 'customerdel' items.pk %}" method="post">
{% csrf_token %}
Cancel
<input name="confirm" type="submit" >
</form>
This is my URL.
path('dashboard/records/customerdel/<int:pk>', views.customerdel, name='customerdel'),
You are doing wrong while template rendering as you are not sending any data to the template.But inside the record.html you are trying to iterate over CustomerData which is not defined.So send it to the template or another way is to simply redirect to the route which is made for rendering record.html.
Here is the full code which you should apply in your django project to make it work.
from django.http import HttpresponseRedirect
from django.urls import reverse #these two lines are required for redirecting to a previous route(url)
As you must have set a url which takes to the records function something like this;
path('records', views.records, name='records')
If you haven't added the name, add it.
Then in views.py, in customerdel function;
if request.method == 'POST':
#write your code which you already wrote and instead of return render(...) write this;
return HttpResponseRedirect(reverse('records')) #where records is the name of the url which takes us to the records page.

How does Django urls are matched?

I have a page with a form in it. Its url is
url('tasks/searchBook', views.searchBook, name='searchBook'),
when I click the submit button of form, it should go to this url
url('tasks/searchBookResult/', views.searchBookResult, name='searchBookResult'),
Url is changing in address bar but next html file is not rendering.
However if I interchange the place of urls in urls.py file i.e. take the second url on top and first url at bottom then it works fine.
What is happening here?
urls.py file :
urlpatterns = [
url(r'^$', views.index, name='index'),
url('tasks/searchBook/', views.searchBook, name='searchBook'),
url('tasks/searchBookResult/', views.searchBookResult, name='searchBookResult'),
]
form code in template file :
<form action="{% url 'lms:searchBookResult' %}" method="post">
{% csrf_token %}
<div class="inner centerAlign">
<input type="text" id="bookId" name="bookId" placeholder="Book ID" class="inputField"></input>
</div>
<div class="inner centerAlign">
<label>OR</label>
</div>
<div class="inner centerAlign">
<input type="text" id="bookTitle" name="bookTitle" placeholder="Book Title" class="inputField"></input>
</div>
<div class=" inner centerAlign">
<input type="submit" value="Search" class="button button-primary" name="searchBook"></input>
</div>
</form>
views.py :
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
def index(request):
return render(request, 'lms/loginPage.html')
def searchBook(request):
return render(request,'lms/tasks/searchBook.html')
def searchBookResult(request):
return render(request,'lms/tasks/searchBookResult.html')
Url's are matched as regexes in the order they are shown in the urls.py.
Since searchBook matches before searchBookResult, the first page is returned.
Simply reorder these so searchBookResult url is before the other.
url('tasks/searchBookResult/', views.searchBookResult, name='searchBookResult'),
url('tasks/searchBook/', views.searchBook, name='searchBook'),
Alternatively, you can include a $ at the end of your url which indicates the end of a line
url('tasks/searchBook/$', views.searchBook, name='searchBook'),

Django can't process html form data

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

Categories