I want to create an "index.html" Django template, which contains a button. When the button is pressed, I want to render the template "home.html", which itself displays the value "123". (Of course, there is a simpler way to do this specific task - but I am learning Django and so want to try it this way.)
Here is my views.py file:
from django.shortcuts import render
def home(request, x)
context = {'x': x}
return render(request, 'home.html', context)
Here is my urls.py file:
from django.conf.urls import patterns, include, url
from myapp import views
urlpatterns = patterns('',
url(r'^$', views.index, name='index'),
url(r'^home', views.home, name='home'),
)
Here is my home.html file:
<html>
<body>
The value is: {{ x }}
</body>
</html>
Finally, here is my index.html file:
<html>
<form method="post" action=???>
<input type="button" value="Click Me">
</form>
Please can somebody tell me what I need to write in place of the ???, in the action attribute above? I have tried setting ??? = "{% url 'home' 123 %}" but this gives me a "NoReverseMatch" error. Therefore, I suspect there may be also be something wrong with my urls.py file...
Thank you!
Rewrite your index.html like this
<html>
<form method="post" action=/home>
<input type="hidden" name="my_value" value="123">
<input type="button" value="Click Me">
</form>
It contains a hidden variable called my_value its hold your value 123. And i your view.py accept this value like this,
from django.shortcuts import render
def home(request)
x = ' '
if request.POST:
x = request.POST['my_value']
context = {'x': x}
return render(request, 'home.html', context)
You get the NoReverseMatch error because you do not have a url that captures the 123 that you send along with the url. Let me tell you an easy way:
You can set the action as something like:
action="/home/123" # or any integer you wish to send.
And match that url in urls py by modifying the home url as:
url(r'^home/(?P<x>\d+)/$', views.home, name='home')
This passes whatever parameter you send in the home url(which should be an integer in this case) as x. Thus the x will be displayed in the home.html
Related
I was doing some practical with django for Post and Get request and some security related stuff related to urls so I made a form in a html file in which I have used method as post and when it is going inside the views template then it is showing my method as GET I am not able to figure it out so please solve my issue thank you! I am attaching screenshot with this Post for your reference.
This code is for my form page in which I have used method as post
I have attached my 'check function' in which it is always going to the else block and not if block
Here I have attached my browser screen which shows that my method is using GET request
Code(HTML) :-
{% block body %}
<form action="check" method="post">
{% csrf_token %}
<div class="form-group">
<label for="exampleInputEmail1">Email address</label>
<input type="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" name="email">
<small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small>
</div>
<div class="form-group">
<label for="exampleInputPassword1">Password</label>
<input type="password" class="form-control" id="exampleInputPassword1" name="password">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
{% endblock body %}
Code (Python) :-
def check(request):
if request.method == 'POST':
return HttpResponse("Now url is not having your E-mail and Password")
else:
return HttpResponse("Using url (you can also see your email and password in url) we can easily delete your "
"account which is a major flaw in html GET request which "
"is set by default in form tag! Method used: {}".format(request.method))
So The above is returning the else part of the python code instead of if part and I have seen the request.method function is giving the output as "GET"
URLS in my django app:
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name="index"),
path('find', views.find, name="find"),
path('form_index/', views.form_index, name="form_index"),
path('form_index/check/', views.check, name="check"),
]
URLS in my main project :-
"""testing URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/3.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, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('sse.urls')),
]
in your views, do something like:
def check(request):
if request.method == 'POST':
return HttpResponse("This is POST request")
else:
return render(request, "form.html")
I'm trying to click on a button in http://127.0.0.1:8000/main/electronics/switch/ to call getCommodityCommentDetail to do something, and then redirect to another page commodityInfoPage.
What puzzles me is that the page always shows the same content in the initial page, although the url has changed e.g. to http://127.0.0.1:8000/main/comments/1/.
After testing, I found that the commodityInfoPage in views.py isn't called. I have searched long time for solutions, but all of them failed. So how can I fix it?
urls.py:
app_name = 'main'
urlpatterns = [
# eg:127.0.0.1:8000/main/
path('', views.index, name = 'index'),
path('getCommodityInfo/', views.getCommodityInfo, name = 'getCommodityInfo'),
path('getCommodityCommentDetail/', views.getCommodityCommentDetail, name="getCommodityCommentDetail"),
path('<str:category>/<str:searchKey>/',views.commodityInfoPage, name = 'commodityInfoPage'),
path('comments/<str:commodityId>/', views.commodityCommentPage,name = 'commodityCommentPage'),
]
view.py:
def getCommodityCommentDetail(request):
if request.method=="POST":
commodityId = request.POST.get("commodityId")
# scrapy module is waiting implementation
#
return HttpResponseRedirect(reverse('main:commodityInfoPage',args=(commodityId)))
def commodityCommentPage(request, commodityId):
print("enter commodityCommentPage")
commentList = JDCommentDetail.objects.all()
context = {'commentList':commentList}
return render(request,'main/commodityCommentPage.html',context)
templates:
<form action="{% url 'main:getCommodityCommentDetail'%}" method="POST">
{% csrf_token %}
<input class="hidden" value="{{commodity.id}}" name="commodityId">
<button type="submit" class="btn btn-default" >review</button>
</form>
The problem is that comments/1/ is matched by the commodityInfoPage URL pattern.
path('<str:category>/<str:searchKey>/',views.commodityInfoPage, name='commodityInfoPage'),
You can fix this problem by changing the URL patterns so that they don't clash, or by moving the commodityCommentPage URL pattern above the commodityInfoPage one.
path('comments/<str:commodityId>/', views.commodityCommentPage, name='commodityCommentPage'),
path('<str:category>/<str:searchKey>/', views.commodityInfoPage, name='commodityInfoPage'),
Note that if you re-order the patterns, you won't be able to view commodityInfoPage if the category is 'comments'.
I am trying to create a simple Django webpage that uses forms, but my forms are not visible. I have read all of the Django docs and read multiple questions related to this issue, but I have found no solution that fixes my problem.
Here are the relevant files:
views.py
from django.shortcuts import render
from .forms import FileForm
with open('calendar.txt') as f:
file_content = f.read()
def home(request):
return render(request, 'main/index.html',{'file_content':file_content})
def form_get(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = FileForm(request.POST)
# check whether it's valid:
if form.is_valid():
pass
else:
form = FileForm()
return render(request, 'index.html', {'form': FileForm.form})
urls.py
from django.conf.urls import url
from django.contrib import admin
from main import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', views.home, name='home'),
]
index.py
{% extends "base.html" %}
{% block content %}
<h1>Welcome to the calendar!</h1>
<form action="/#" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit">
</form>
{{form}}
{% endblock content %}
Link to program
From what I have read, I suspect there may be an issue in the urls.py file, but I've been looking over it many times and I haven't found anything wrong. Any thoughts?
Try
def form_get(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = FileForm(request.POST)
# check whether it's valid:
if form.is_valid():
pass
else:
form = FileForm()
return render(request, 'main/index.html', {'form': form})
See how I changed the context for the render from {'form': FileForm.form} to {'form': form}. The path to the index.html file was also wrong.
After fixing the view, you need to add an actual URL to go to it. Your current URL has
url(r'^$', views.index, name='home'),
Note how is using views.index and not views.form_get. Change the URL to use form_get and it will work.
url(r'^$', views.form_get, name='home'),
Don't know if you want to have / go to the form, or if you would rather have / still go to home, where you have a link to the form. But in that case, you do not want to share the same index.html file.
But seems like you may be trying to merge those two, but in that case, you need a single view, which can both show the content of the file, and ask for the file. But will be easier if you have two views, and leave the form to just take the input, and then redirect to the second view to show the results.
I am learning Django and am trying to create a form that I can submit a participant's information to the database.
I have an index view, which list all the participants:
http://127.0.0.1:8000/participants/
Clicking a button on the index will go to form submission:
http://127.0.0.1:8000/participants/add_participant/
After submitting the form, the page goes back to the index view, but the URL is not correct, it stucks at http://127.0.0.1:8000/participants/add_participant/
If I refresh the browser immediately, it will add another record to the database.
add_participant.html
<!DOCTYPE html>
<html>
<head>
<title>This is the title</title>
</head>
<body>
<h1>Add a Participant</h1>
<form id="participant_form" method="post" action="/participants/add_participant/">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" name="submit" value="Create Participant" />
</form>
</body>
</html>
views.py
from django.shortcuts import render, get_object_or_404, redirect
from django.http import HttpResponse, HttpResponseRedirect
from participants.models import Participant
from .forms import ParticipantForm
# Create your views here.
def index(request):
participant_list = Participant.objects.order_by('-first_name')[:50]
context = {'participants': participant_list}
return render(request, 'participants/index.html', context)
def add_participant(request):
if request.method == 'POST':
form = ParticipantForm(request.POST)
if form.is_valid():
form.save(commit=True)
return index(request)
else:
form = ParticipantForm()
return render(request, 'participants/add_participant.html', {'form': form})
urls.py
from django.conf.urls import url
from . import views
from .models import Participant
app_name = 'participants'
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'add_participant/$', views.add_participant, name='add_participant'),
]
I tried switching the
return index(request)
to:
return HttpResponseRedirect("http://127.0.0.1:8000/participants/")
It solves the problem...but I doubt this is the "right" way to do it. What is the correct way to fix this issue?
You can pass just the path to the redirect response:
return HttpResponseRedirect("/participants/")
This way if you change your domain, the redirect will work.
an other solution is to use reverse
from django.core.urlresolvers import reverse
# ...
return HttpResponseRedirect(reverse(index))
My underlying struggle is I am having trouble understanding how django templates, views, and urls are tied together... What is the simplest, bare minimum way to prompt the user to input a string, then use that string to query a database (preferably w/ python model not raw sql queries)? Should I use GET and POST methods? Should I use a form? Do I need to use a template or can I use a generic view?
when i try submitting input it just reloads the input page.
views.py:
from django.shortcuts import render
from django.shortcuts import HttpResponse
from People.models import Person
def index(request):
return render(request, 'People/index.html')
def search(request):
search_id = request.POST.get('textfield', None)
try:
user = Person.objects.get(MAIN_AUTHOR = search_id)
#do something with user
html = ("<H1>%s</H1>", user)
return HttpResponse(html)
except Person.DoesNotExist:
return HttpResponse("no such user")
urls.py
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^People/', 'People.views.index'),
url(r'^People/send/', 'People.views.search'),
)
template:
<form method="POST" action="send/">
{% csrf_token %}
<input type="text" name="textfield">
<button type="submit">Upload text</button>
</form>
Am I missing something or doing something wrong?
If I understand correctly, you want to take some input from the user, query the database and show the user results based on the input. For this you can create a simple django form that will take the input. Then you can pass the parameter to a view in GET request and query the database for the keyword.
EDIT:
I have edited the code. It should work now.
views.py
from django.shortcuts import render
from django.shortcuts import HttpResponse
from .models import Person
from django.core.exceptions import *
def index(request):
return render(request, 'form.html')
def search(request):
if request.method == 'POST':
search_id = request.POST.get('textfield', None)
try:
user = Person.objects.get(name = search_id)
#do something with user
html = ("<H1>%s</H1>", user)
return HttpResponse(html)
except Person.DoesNotExist:
return HttpResponse("no such user")
else:
return render(request, 'form.html')
urls.py
from django.conf.urls import patterns, include, url
from People.views import *
urlpatterns = patterns('',
url(r'^search/', search),
url(r'^index/', index)
)
form.html
<form method="POST" action="/search">
{% csrf_token %}
<input type="text" name="textfield">
<button type="submit">Upload text</button>
</form>
Also make sure that you place your templates in a seperate folder named templates and add this in your settings.py:
TEMPLATE_DIRS = (
os.path.join(os.path.dirname(__file__), '../templates').replace('\\','/'),
)
For a user input you'll need 2 views - one to display the page with the form and another to process the data. You hook the first view to one url, say "feedback/", and the other one to a url like "feedback/send/". You also need to specify this second url in your form tag.
<form method="POST" action="feedback/send/">
<input type="text" name="textfield">
...
<button type="submit">Upload text</button>
</form>
Now in the second view you can obtain the form data and do whatever you want with it.
def second_view(request):
if request.method == "POST":
get_text = request.POST["textfield"]
# Do whatever you want with the data
Take a look at this page Fun with Forms. It'll give you the basic understanding. I would also advice to work through the whole book.
You should use ether GET or POST (GET is probably not secure). Using form is not mandatory, as you can style it and perform all the validation yourself and then pass the data straight to the model.