I am still learning Django. I have been looking at various tutorials but I am struggling with forms on django framework.
The problem is that I am unable to display the form field for email on the base.html page. It is basically a subscription form. I am still new to django. This is what I have made till now.
models.py
from django.db import models
class SubscribeModel(models.Model):
email = models.CharField(max_length=100)
forms.py
from django import forms
from models import SubscribeModel
class SubscribeForm(forms.ModelForm):
class Meta:
model=SubscribeModel
views.py
def loadform(request):
form = SubscribeForm()
return render_to_response('base.html', {'form': form},context_instance=RequestContext(request))
base.html
<html>
...
<form action="" method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Subscribe"></ul>
</form>
...
</html>
urls.py
urlpatterns = patterns('',
url(r'^$', 'chsite.blog.views.index'),
url(r'^$', 'chsite.blog.views.loadform'),
url(r'^admin/', include(admin.site.urls)),
)
Once you are edited the question, I can see two url(---) reffenceced to the same url. Hence Django will loadd the first one. It means you never load the loadform view. So try removing the line:
url(r'^$', 'chsite.blog.views.index'),
or edit the actual tuple for the loadform for instance:
url(r'^suscribe/$', 'chsite.blog.views.loadform'),
and go to your browser at 127.0.0.1:8000/suscribe/ url.
You have to define different url patterns as your first two are identical. URL processing stops at first hit, in your case uses index view.
Related
I am doing a simple form site with Django. This is what my sites url is looks like: mysite.com/register/12345678
I want to print the part after the register (12345678) to the order id field. When someone goes this mysite.com/register/87654321 url then i want to print it.
How can i do that? These are my codes.(Currently using Django 1.11.10)
forms.py
from django import forms
from .models import Customer
from . import views
class CustomerForm(forms.ModelForm):
class Meta:
model = Customer
fields = (
'order_id','full_name','company','email',
'phone_number','note')
widgets = {
'order_id': forms.TextInput(attrs={'class':'orderidcls'}),
'full_name': forms.TextInput(attrs={'class':'fullnamecls'}),
'company': forms.TextInput(attrs={'class':'companycls'}),
'email': forms.TextInput(attrs={'class':'emailcls'}),
'phone_number': forms.TextInput(attrs={'class':'pncls'}),
'note': forms.Textarea(attrs={'class':'notecls'}),
}
views.py
from django.shortcuts import render
from olvapp.models import Customer
from olvapp.forms import CustomerForm
from django.views.generic import CreateView,TemplateView
def guaform(request,pk):
form = CustomerForm()
if request.method == "POST":
form = CustomerForm(request.POST)
if form.is_valid():
form.save(commit=True)
else:
print('ERROR FORM INVALID')
theurl = request.get_full_path()
orderid = theurl[10:]
return render(request,'forms.py',{'form':form,'orderid':orderid})
customer_form.html
{% extends 'base.html' %}
{% block content %}
<h1>REGİSTRATİON</h1>
<form class="registclass" method="POST">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="btn btn-default">REGISTER</button>
</form>
{% endblock %}
urls.py
from django.conf.urls import url
from django.contrib import admin
from olvapp import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^thanks/$',views.ThankView.as_view(),name='thank'),
url(r'^register/(?P<pk>\d+)',views.guaform,name='custform'),
]
You have passed the value to your view as 'pk' so you can use that to set the the initial value:
views.py
form = CustomerForm(initial={'order_id': pk})
SamSparx is right, here's some additional information to help prevent such errors in advance:
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^thanks/$',views.ThankView.as_view(),name='thank'),
url(r'^register/(?P<pk>\d+)',views.guaform,name='custform'),
]
You are using regex to parse your path. Regex is generally speaking not recommended in this case according to the docs because it might introduce more errors and is harder to debug. (Unoptimized) RegEx also tends to be slower.
For simple use cases such as your path here, consider choosing the default pathing syntax as below:
urlpatterns = [
url('admin/', admin.site.urls),
url('thanks/',views.ThankView.as_view(),name='thank'),
url('register/<int:pk>',views.guaform,name='custform'),
]
You could of course also use string instead of int depending on your usage of pk.
Your paths do not all end with a slash consistently. This might impact your SEO and confuse users. See this and this.
Also your form is not imported .as_view() for some reason which could cause some problems.
I am creating an app where user can search for recipes by ingredients. I want that logged in user can add recipe by himself. I have created form where i am using ModelForm. Now i want to do that after user push submit recipe will be added/saved to recipes which i can see in admin panel and also it will be possible to search for it, but now it looks like it is impossible to save the new recipe...
My code in view:
def add_recipe(request):
if not request.user.is_authenticated:
return redirect('login_required')
add_recipe = RecipeForm(request.POST or None)
if add_recipe.is_valid():
print("your recipe has been added!")
add_recipe.save()
template = "drinks/add_recipe.html"
return render(request, template, {'RecipeForm': add_recipe})
My form:
from django.forms import ModelForm
from drinks.models import Recipe
class RecipeForm(ModelForm):
class Meta:
model = Recipe
fields = ['recipe_name', 'preparation', 'ingredients']
My templates add_recipe:
<form method="post" action="">
{% csrf_token %}
<table>
{{RecipeForm}}
</table>
<input type="submit" value="Add recipe"/>
</form>
my urls:
urlpatterns = [
path('', views.drink_list, name='drink_list'),
path('search/', views.search_results, name='search_results'),
path('no_name/', views.drink_list, name='drink_list'),
path('signup/', views.signup, name='signup'),
path('add_recipe/', views.add_recipe, name='add_recipe'),
path('login_required/', views.login_required, name='login_required'),
]
I am not sure what you are trying to do with your views (their names are not very explicit), but have you registered the view through your urls.py file?
Also, action="" in your template won't do anything. You need to specify the url to send your post request! action should not be equaled to "", but to the url you want to submit your form. In your case, you should have action="{% url 'add_recipe' %}"
I'm making a simple web server to take html input data and insert it to data base table .
I've tried with POST request got into more CSRF troubles , Turned to GET request to go over CSRF (not necessary in my case ) , still not able to GET the html data into Database .
myapp/models.py
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=300, unique=True)
content = models.TextField()
myapp/templates/createpost.html
<head>
<title>Create a Post </title>
</head>
<body>
<h1>Create a Post </h1>
<form action="" method="GET">
{%csrf_token%}
Title: <input type="text" name="title"/><br/>
Content: <br/>
<textarea cols="35" rows="8" name="content">
</textarea><br/>
<input type="submit" value="Post"/>
</form>
</body>
</html>
myapp/views.py
from django.shortcuts import render
from .models import Post
def createpost(request):
if request.method == 'GET':
if request.GET.get('title', None) and request.GET.get('content', None):
post = Post()
post.title = request.GET.get('title', None)
post.content = request.GET.get('content', None)
post.save()
return render(request, 'createpost.html')
else:
return render(request, 'createpost.html')
urls.py
from django.contrib import admin
from django.urls import path, include
from django.views.generic.base import TemplateView
urlpatterns = [
path('admin/', admin.site.urls),
path('', TemplateView.as_view(template_name='createpost.html'), name='createpost'),
]
am using Django 2.2.6 with PyCharm community 2019.2.3
I've been searching for almost 2 days , checked django doc , and stackoverflow answers , none was helpful , I had to ask to make sure its not a version related issue and forgive me if i miss understand a simple point am just a beginner.
I've tried with POST request got into more CSRF troubles , Turned to GET request to go over CSRF (not necessary in my case ) , still not able to make it .
Ok.
STOP EVERYTHING RIGHT NOW
Now
do the official Django tutorial and learn to use Django forms and modelforms
read the HTTP spec about the proper use of GET requests (hint: the important word here is "idempotent")
fix your code accordingly
if by then you still have issues with the csrf token, come back and post a question about it (with a proper MCVE etc).
Also note that your question should be claused as either unclear or OT since you didn't explain what your problem is (hint: "doesn't work" doesn't explain anything). But anyway...
What you want (nb: models unchanged) is:
myapp/forms.py
from django import forms
from . models import Post
class PostForm(forms.ModelForm):
class Meta(object):
model = Post
fields = ("title", "content")
views.py
from django.shortcuts import redirect, render
from . models import Post
from . forms import PostForm
def createpost(request):
if request.method == 'POST':
form = PostForm(request.POST)
if form.is_valid():
form.save()
# read the doc for `redirect` and change the destination to
# something that makes sense for your app.
# as to why we redirect, cf https://en.wikipedia.org/wiki/Post/Redirect/Get
return redirect("/")
else:
# GET request, present an empty form
form = PostForm()
return render(request, 'createpost.html', {"form": form})
urls.py
from django.contrib import admin
from django.urls import path, include
# NB: actually you should define myapp's urls in
# myapp/urls.py and `include` them here
from myapp.views import createpost
urlpatterns = [
path('admin/', admin.site.urls),
path('/', createpost, name='createpost'),
]
myapp/templates/createpost.html
<head>
<title>Create a Post </title>
</head>
<body>
<h1>Create a Post </h1>
<form action="" method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Post"/>
</form>
</body>
</html>
I can't garantee this will work out of the box (I'd have to post a full project with proper settings etc to be sure - and actually to test it at least once for typos etc) but that's the correct way of doing things.
I've been searching for almost 2 days
That's 2 days wasted, that you would have better used doing the official Django tutorial. I also suggest you learn to debug programs - just adding a couple ̀print("XXX")` calls in your view and checking your devserver's outputs would have made clear why nothing got created in your database (hint: with your original urls.py, you are NEVER calling your view function).
I have a simple class based view (in an app video) that is creating an object using a form in a template (upload_video.html). When I submit the form, I just want to redirect to the home page, or the root index. It seems like this should be so easy. I am getting an error saying there is no page. I have tried several different ways of doing this, the code i have below is just one example.
views.py
class UploadVideo(CreateView):
model = Video
fields = ['title', 'description']
template_name = 'upload_video.html'
success_url = reverse_lazy('index.html')
upload_video.html
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Upload Video"/>
</form>
</body>
</html>
root.urls
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', index),
url(r'^video/', include('video.urls'))
Error
Page not found (404)
Request Method: GET
Request URL: http://127.0.0.1:8000/video/index.html
Using the URLconf defined in flash2.urls, Django tried these URL patterns, in this order:
^admin/
^$
^video/ ^upload [name='upload']
The current URL, video/index.html, didn't match any of these.
You need to pass urlname to the revers_lazy method, not the template name. Try to change in url.py:
url(r'^$', index, name="index")
And in UploadVideo class:
success_url = reverse_lazy('index')
I am attempting to install and test django-honeypot from sunlightlabs using the provided templates.
the application does not come accompanied with models nor views and I am confused as to how I am supposed to get the app to work. I have attempted to play with the urls to call the templates.
my mysite/mysite/urls.py follows:
from django.conf.urls.defaults import *
urlpatterns = patterns('',
#url(r'^$', include('honeypot.urls')),
)
and my mysite/honeypot/urls.py follows:
from django.conf.urls.defaults import *
#from tagging.views import tagged_object_list
from django.conf.urls import patterns, include, url
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.shortcuts import render
from django.contrib import admin
urlpatterns = patterns('',
url(r'^$', render, dict(template_name='/home/mohrashak/attribute2/honeypot/templates/honeypot/webpage.html'), name='price'),
)
ROOT_URLCONF="honeypot.urls"
where webpage is
{% load honeypot %}
<form>
{% render_honeypot_field "field_name" %}
</form>
and my understanding is that something will be entered into the box be processed using the application. But there is no model. What am I missing?
You don't need to worry about models or views for django-honeypot. It is installed into the site-packages folder of your Python library so you don't have to write models/views/urls.py for you - these are all there in your pythonpath.
Make sure you read the online documentation for installing the app.
Here is the checklist:
Add honeypot to INSTALLED_APPS in settings.py;
Define HONEYPOT_FIELD_NAME which is the name to use for the honeypot field in your form. Try not to use 'honeypot' though as some bots will avoid it.
Make sure you add {% load honeypot %} in the top of your template using django-honeypot;
Then use the following tag in any form {% render_honeypot_field "field_name" %}
When your form is submitted - you can use the check_honeypot decorator from honeypot.decorators to check the value is present (or not by default) and correct.
Here is the example from the documentation to add to your view:
from honeypot.decorators import check_honeypot
#check_honeypot(field_name='hp_field_name')
def post_comment(request):
...
#check_honeypot
def other_post_view(request):
...
Edit1:
In response to your comment:
Yes;
Yes.
No - the nature of django-honeypot is that it prevents "form spam". So you have to have at least a form in your template. You should pass a form from a view to a template. More information in the documentation. I've written a near full example below.
Example of a contact form using django-honeypot
Note: This is untested.
This is an example that creates and shows a contact form (by going to a /contact/ URL) and then handles the form being submitted. Imagine we have used django_admin.py startapp contact_app
urls.py
Your urls file takes the /contact/ URL passes the request to our contact view.
from django.conf.urls import patterns, url
urlpatterns = patterns('',
url(r'^contact/$', 'contact_app.views.contact'),
)
contact_app/views.py
Your views file takes the request, and handles GET and POST requests. If the request is a GET it passes an empty form to the template. If a POST then it checks the form is valid and processes the form. We wrap it in the check_honeypot decorator to make sure it passes our django-honeypot test.
from contact_app.forms import ContactForm
from honeypot.decorators import check_honeypot
#check_honeypot
def contact(request):
if request.method == 'POST': # If the form has been submitted...
form = ContactForm(request.POST) # A form bound to the POST data
if form.is_valid(): # All validation rules pass
# Process the data in form.cleaned_data
# ...
return HttpResponseRedirect('/thanks/') # Redirect after POST
else:
form = ContactForm() # An unbound form
return render(request, 'contact.html', {
'my_form': form,
})
contact_app/forms.py
Here we specify the form fields that are going to be required and display in the template.
from django import forms
class ContactForm(forms.Form):
subject = forms.CharField(max_length=100)
message = forms.CharField()
sender = forms.EmailField()
cc_myself = forms.BooleanField(required=False)
templates/contact.html
From our view, we pass our form (called my_form) to our template and use django's templating language to render each field as a <p></p>. We also load the honeypot and insert the necessary field.
{% load honeypot %}
<form action="/contact/" method="post">{% csrf_token %}
{{ my_form.as_p }}
{% render_honeypot_field "field_name" %}
<input type="submit" value="Submit" />
</form>