Hello i can't make my form work. The button is displayed but the charfield never shows up. I tried to use a if statement with the "sent" parameter and it worked. I just followed the django doc. I did not find a solution in other posts.
Here is my forms.py:
from django import forms
class CharacterForm(forms.Form):
character_name = forms.CharField(label='Search', max_length=30)
views.py:
from django.shortcuts import render
from .forms import CharacterForm
def index(request):
return render(request, 'perso/pages/index.html')
def get_character(request):
character_name = ''
sent = False
if request.method == 'POST':
form = CharacterForm(request.POST)
if form.is_valid():
character_name = form.cleaned_data['character_name']
sent = True
else:
form = CharacterForm()
return render(request, 'perso/pages/index.html', {
'form': form,
'character_name': character_name,
'sent': sent
})
Perso is the name of the app, Urls.py in perso:
from django.conf.urls import url
from . import views
app_name = 'perso'
urlpatterns = [
url(r'^$', views.index, name="index"),
]
My form in template index of perso:
<form action="{% url "perso:index" %}" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>
Here is what appears in the browser:
<form action="/perso/" method="post">
<input type='hidden' name='csrfmiddlewaretoken' value='IWmBEknyibHw4LpvjnyfLWKcUOXLbw27RdHgR7GjhTDelCLGZ51QeF3y9wRyC0Mg' />
<input type="submit" value="Submit" />
</form>
The charfield is missing. No error in the console.
You have some anomaly in your code you missed out the template name argument in your render function. Provide the template name of your corresponding HTML file in the render function. You also missed providing default arguments of character_name and sent variable. See docs here
from django.shortcuts import render
from .forms import CharacterForm
def get_character(request):
character_name = ''
sent = False
if request.method == 'POST':
form = CharacterForm(request.POST)
if form.is_valid():
character_name = form.cleaned_data['character_name']
sent = True
else:
form = CharacterForm()
return render(request, 'template_name.html', {
'form': form,
'character_name': character_name,
'sent': sent
})
You have made mistake to not make urls.py pattern for the function in views.py that is setting the form in the template
from django.conf.urls import url
from . import views
app_name = 'perso'
urlpatterns = [
url(r'^$', views.index, name="index"),
url(r'^character$', views.get_character, name="character"),
]
Also you need correction in your template in your post request URL link
<form action="{% url "perso:character" %}" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>
Now your form will be avaliable at http://localhost:8000/character
Related
I am trying to implement form in django, where I will take input from user, e.g, its table name and then I want to show all the content on the webpage. So, far I tried below code.
views.py
from django.shortcuts import render
# Create your views here.
from django.shortcuts import HttpResponse
from .models import my_custom_sql
from django.core.exceptions import *
def index(request):
return render(request, 'forms_spy/form.html')
def search(request):
if request.method == 'POST':
search_id = request.POST.get('textfield', None)
try:
webpages_list = my_custom_sql.objects.get(name = search_id)
data_list = {'access_record':webpages_list}
return render(request,'forms_spy/index.html', context=data_list)
except my_custom_sql.DoesNotExist:
return HttpResponse("no such user")
else:
return render(request, 'forms_spy/form.html')
forms_spy/models.py
from django.db import models
# Create your models here.
def my_custom_sql(TABLE):
with connections["my_oracle"].cursor() as cursor:
cursor.execute("SELECT * FROM {};".format(TABLE))
row = cursor.fetchall()
return row
templates/forms_spy/form.html
<form method="POST" action="/search">
{% csrf_token %}
<input type="text" name="textfield">
<button type="submit">Upload text</button>
</form>
urls.py under project folder:
from django.contrib import admin
from django.urls import path
from django.conf.urls import url,include
from forms_spy.views import *
urlpatterns = [
# url(r'^$', views.index, name='index'),
#url(r'^', include('livefleet.urls', namespace='livefleet')),
path('admin/', admin.site.urls),
url(r'^search/', search),
url(r'^index/', index),
]
I referred to this link. When I entered the value getting below error.
RuntimeError at /search
You called this URL via POST, but the URL doesn't end in a slash and you have APPEND_SLASH set. Django can't redirect to the slash URL while maintaining POST data. Change your form to point to 127.0.0.1:8000/search/ (note the trailing slash), or set APPEND_SLASH=False in your Django settings.
change in urls.py
from
url(r'^search/', search),
to
url(r'^search/', search, name='search'),
<form method="POST" action="{% url 'search' %}">
{% csrf_token %}
<input type="text" name="textfield">
<button type="submit">Upload text</button>
</form>
ur url is search/ , so u need to put the same in the form action
change urls to
path('search/', search)
slash character for dynamic route, example call in browser (http://domain/search) or (http://domain/search/) if you using both it's work.
templates
<form method="POST" action="/search/">
{% csrf_token %}
<input type="text" name="textfield">
<button type="submit">Upload text</button>
</form>
I'm newbie and trying to do something pretty basic after reading the Django Doc Project Documentation, but can't seem to figure it out. I'm getting a user's name with a POST and trying to GET it and display it on the same page. I'm getting an error: hello() missing 1 required positional argument: 'greeting_id'
I'm using Django 2 and wondering if it could be something with the routing? I'm not exactly sure as I'm very new to MVC and Django.
Any help in the right direction would be greatly appreciated.
Here's my code so far:
Views.py
from django.shortcuts import render
from django.http import HttpResponse
from .models import Greeting
# create hello view
def hello(request, greeting_id):
if request.method == 'POST':
if request.POST['firstname']:
greeting = models.Greeting()
greeting.firstname = request.POST['firstname']
greeting.save()
obj = models.Greeting.objects.get(pk=greeting_id)
context = {
'object': obj
}
return render(request, 'greetings/home.html', context)
return render(request, 'greetings/home.html')
Models.py
from django.db import models
# Create your models here.
class Greeting(models.Model):
firstname = models.CharField(max_length=100)
# returns post object in admin interface
def __str__(self):
return self.firstname
urls.py
from django.contrib import admin
from django.urls import path
from greetings import views #import greetings views into the url file
urlpatterns = [
path('admin/', admin.site.urls),
path('hello/', views.hello, name='hello'),
]
home.html
{% block content %}
<h2>Let's Say Hello!</h2>
<br/>
<br/>
<div>
<form method="POST" action="{% url 'hello' %}">
{% csrf_token %}
Enter your first name:
<br />
<input type="text" name="firstname" />
<br />
<br />
<input type="submit">
</form>
{{ object.firstname }}
</div>
{% endblock %}
Your view "hello" requires an parameter "greeting_id"
def hello(request, greeting_id):
These parameters are passed from the url routing to the view, for the view to work your url would have to look like this
path('hello/<int:greeting_id>/', views.hello, name='hello'),
Where is greeting_id supposed to be coming from?
I have a login form with POST method and when I submit the login data, it goes straight to the empty url and doesn't execute the login method in views.py. Ideally, after I submit the form in www.url.com/login via submit button, it should return a HttpResponse but instead, it takes me to www.url.com/
I am new to Django, I'd appreciate it if you could look into it. Thanks!
home.html
<center><h1>Welcome to my website</h1>
<form method='POST'> {% csrf_token %}
{{ form }}
<button type='submit' class='btn btn-default'>Submit</button>
</form>
</center>
urls.py
from django.contrib import admin
from django.urls import path
from .views import home, login
urlpatterns = [
path('', home),
path('login/', login),
path('admin/', admin.site.urls),
]
forms.py
from django import forms
class LoginForm(forms.Form):
username = forms.CharField(widget=forms.TextInput(attrs={"class":"form-control", "placeholder":"Your username"}))
password = forms.CharField(widget=forms.PasswordInput(attrs={"class":"form-control", "placeholder":"Your password"}))
views.py
from django.contrib.auth import authenticate, login
from django.http import HttpResponse
from django.shortcuts import render
from .forms import LoginForm
def home(request):
context={
"form": "Test"
}
return render(request, "home.html", context)
def login(request):
login_form = LoginForm(request.POST or None)
context={
"form": login_form
}
if login_form.is_valid():
username = login_form.cleaned_data.get('username')
password = login_form.cleaned_data.get('password')
user = authenticate(request, username=username, password=password)
if user is not None:
#request.user.is_authenticated()
login(request, user)
return HttpResponse("You are now logged in")
else:
return HttpResponse('Error')
return render(request, "home.html", context)
First, you should set an attribute action in the form which set a url to send.
Second, a url value in action must be clear. It's not a matter of Django but HTML.
I'd like to recommend you to use absolute path. If you use relative path, a slash string would be added whenever you send a request.
<form action="/login/" method='POST'>
{% csrf_token %}
{{ form }}
<button type='submit' class='btn btn-default'>Submit</button>
</form>
This is because your form doesn't contain action, i.e. where should the POST call be made with the user credentials.
Try following change in home.html:
<center><h1>Welcome to my website</h1>
<form action="" method='POST'> {% csrf_token %}
{{ form }}
<button type='submit' class='btn btn-default'>Submit</button>
</form>
</center>
Following the answers before, it would be a good practice to use named patterns instead of fixed urls.
# urls
...
path('login/', login, name='login'),
...
# template
<form action="{% url 'login' %}" method='POST'>
So if you change for example
login/
for
accounts/login/
You don't have to change the template as well.
urlpatterns = [
re_path('^$', home_page),
re_path('^admin/', admin.site.urls),
re_path('^register/$', register_page, name='register'),
re_path('^login/$', login_page, name='login'),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
I solved this by adding ^$to the beginning and end of the patterns.
I am new to Django , i just created a simple form to store the user input to database, but the data is not stored while clicking submit button, when i click the submit button the current page is refreshed, but data not stored in database. what is wrong in my code ?.I have created the following models, and my code is ,
mysite/jobs/models.py
from django.db import models
class Cost(models.Model):
cost = models.FloatField()
date = models.DateField()
mysite/jobs/views.py
from django.shortcuts import render
from jobs.forms import CostForm
from jobs.models import Cost
def costView(request):
if request.method == 'POST':
form = CostForm(request.POST)
if form.is_valid():
date = request.POST.get('date','')
cost = request.POST.get('cost','')
cost_obj = Cost(date=date, cost=cost)
cost_obj.save()
return HttpResponse("csdfsdf")
else:
form = CostForm()
return render(request,'jobs/cost.html',{'form':form,})
mysite/jobs/forms.py
from django import forms
class CostForm(forms.Form):
date = forms.DateField()
cost = forms.FloatField()
mysite/jobs/templates/jobs/cost.html
<form action="{% url 'jobs:cost' %}" method="post"> {% csrf_token %}
<p><label for="date">Date:</label><input type="text" name="date" value={% now "Y-m-d" %}/></p>
<p><label for="cost">Cost:</label><input type="text" name="cost" value="0" id="cost"/></p>
<input type="submit" value="Submit"/>
</form>
mysite/jobs/urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.costView, name='cost'),
]
mysite/urls.py
from django.conf.urls import url, include
from django.contrib import admin
urlpatterns = [
url(r'^', include('jobs.urls',namespace="jobs")),
url(r'^polls/', include('polls.urls')),
url(r'^admin/', admin.site.urls),
]
Your form is presumably not valid.
You should use {{ form.errors }} in the template to display the validation errors. Also, you should use {{ form.date }} and {{ form.cost }} to display the fields, rather than creating input tags manually, so that the values are re-populated when validation fails.
Since you made mysite/jobs/forms.py, you can use that in your HTML template:
<form action="{% url 'jobs:cost' %}" method="post"> {% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit"/>
</form>
The reason why your form wasn't saving is probably because of your mysite/jobs/views.py. Since you don't need to add additional data besides the date and cost in the form, you can go ahead and save it instead of creating cost_obj:
if request.method == 'POST':
form = CostForm(request.POST)
if form.is_valid():
form.save()
If you do want to create cost_obj, do it this way:
cost_obj = form.save(commit=False)
You can then add additional information into the object before saving it. e.g.:
cost_obj.user = request.user
cost_obj.save()
I am trying to configure HTML formto work with Django Models rather than using built-in Forms in the framework. I have made the form using Html below and have pasted the code for Model, View and Urls.py. The problem is when I click the submit button, it doesn't perform any action. I am able to view the form but it doesn't serves the purpose. I know the question is very lame, but how would configure the HTML to work with the django model so that the data can be saved to the database?
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body style="font-family:Courier New">
<h1>Add / Edit Book</h1>
<hr/>
<form id="formHook" action="/istreetapp/addbook" method="post">
<p style="font-family:Courier New">Name <input type="text" placeholder="Name of the book"></input></p>
<p style="font-family:Courier New">Author <input type="text" placeholder="Author of the book"></input></p>
<p style="font-family:Courier New"> Status
<select>
<option value="Read">Read</option>
<option value="Unread">Unread</option>
</select>
</p>
<input type="submit" id="booksubmit" value="Submit"></input>
</form>
</body>
</html>
View
from django.shortcuts import HttpResponse
from istreetapp.models import bookInfo
from django.template import Context, loader
from django.shortcuts import render_to_response
def index(request):
booklist = bookInfo.objects.all().order_by('Author')[:10]
temp = loader.get_template('app/index.html')
contxt = Context({
'booklist' : booklist,
})
return HttpResponse(temp.render(contxt))
Model
from django.db import models
class bookInfo(models.Model):
Name = models.CharField(max_length=100)
Author = models.CharField(max_length=100)
Status = models.IntegerField(default=0) # status is 1 if book has been read
def addbook(request, Name, Author):
book = bookInfo(Name = Name, Author=Author)
book.save
return render(request, 'templates/index.html', {'Name': Name, 'Author': Author})
Urls.py
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('app.views',
url(r'^$', 'index'),
url(r'^addbook/$', 'addbook'),
# Uncomment the next line to enable the admin:
url(r'^admin/', include(admin.site.urls)),
)
You forgot to define name in each of your input
<form id="formHook" action="/addbook/" method="post">
{% csrf_token %}
<p style="font-family:Courier New">
Name <input type="text" name="name" placeholder="Name of the book"></input>
</p>
<p style="font-family:Courier New">
Author <input type="text" name="author" placeholder="Author of the book"></input>
</p>
<p style="font-family:Courier New">
Status
<select name="status">
<option value="Read">Read</option>
<option value="Unread">Unread</option>
</select>
</p>
<input type="submit" id="booksubmit" value="Submit"></input>
</form>
Your addbook must be in the views.py not in your models.py.
You don't have to define templates/index.html in your render, it is understood in your settings
def addbook(request):
if request.method == 'POST':
name = request.POST['name']
author = request.POST['author']
bookInfo.objects.create(Name = name, Author=author)
return render(request, 'index.html', {'Name': name, 'Author': author})
main urlconf
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^$', 'project_name.views.index'),
url(r'^addbook/$', 'project_name.views.addbook'),
# Uncomment the next line to enable the admin:
url(r'^admin/', include(admin.site.urls)),
)
You need to add name attributes to your html form then process the form submission in the view. Something like -
from django.http import HttpResponseRedirect
from django.shortcuts import render
def book_view(request):
if request.method == 'POST':
name = request.POST['name']
author = request.POST['author']
book = BookInfo(name=name, author=author)
if book.is_valid():
book.save()
return HttpResponseRedirect('your_redirect_url')
else:
return render(request, 'your_form_page.html')
Have a look at the docs on the request.POST dictionary.
However you really would be better off doing this with a django ModelForm -
class BookForm(ModelForm):
class Meta:
model = BookInfo # I know you've called it bookInfo, but it should be BookInfo
then in your view -
from django.http import HttpResponseRedirect
from django.shortcuts import render
def book_view(request, pk=None):
if pk:
book = get_object_or_404(BookInfo, pk=pk)
else:
book = BookInfo()
if request.method == 'POST':
form = BookForm(request.POST, instance=book)
if form.is_valid():
book = form.save()
return HttpResponseRedirect('thanks_page')
else:
form = BookForm(instance=book)
return render(request, 'your_form_page.html', {'form': form)
And your_form_page.html can be as simple as -
<form action="{% url book_view %}" method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>
Have a look at the docs on working with forms.