I have been reading the django book and the django documentation, but still can figure it out.
i have this model.py:
from django.db import models
from django.forms import ModelForm
class Zonas(models.Model):
name = models.CharField(max_length=30)
def __unicode__(self):
return self.name
class ZonasForm(ModelForm):
class Meta:
model = Zonas
this view.py:
from django import forms
from testApp.models import Zonas
from django.shortcuts import render_to_response
def menuForm (request):
z = list (Zonas.objects.all())
numbers = forms.CharField(max_length=30,
widget=forms.Select(choices=z))
return render_to_response('hello.html', {'numbers':numbers})
this html:
<html>
<body>
<form action="" method="get">
<div class="field">
{{ form.numbers }}
</div>
<input type="submit" value="Submit">
</form>
</body>
</html>
Ans this urls.py:
from django.conf.urls import patterns, include, url
from testApp.views import menuForm
urlpatterns = patterns('',
url(r'^hello/$', menuForm ),
)
All i get when i run the server is a page only with the submit button, and no form.number wich is supossed to be a select menu.
I tried this views.py:
def menuForm (request):
z = list (Zonas.objects.all())
numbers = forms.ChoiceField(choices=z)
return render_to_response('hello.html', {'numbers':numbers})
But the result is the same...
Any hints? Should i use a diferent return?
You are trying to access {{ form.numbers }} when you never pass a form variable to the template. You would need to access numbers directly with {{ numbers }}.
Also you aren't quite using forms correctly. Check this out https://docs.djangoproject.com/en/dev/topics/forms/
Create a menu form that contains a ModelChoiceField
forms.py
class MenuForm(Form):
zonas = forms.ModelChoiceField(queryset=Zonas.objects.all())
Now use that form in your view
views.py
from myapp.forms import MenuForm
def menuForm(request):
if request.method == 'POST': # If the form has been submitted...
form = MenuForm(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('/success/') # Redirect after POST
else:
form = MenuForm() # An unbound form
return render(request, 'hello.html', {
'form': form,
})
Now you can use the form in your template
hello.html
<html>
<body>
<form action="" method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit">
</form>
</body>
</html>
How about using ModelChoiceField? This code works for me.
views.py:
from django import forms
from models import Zonas
from django.shortcuts import render_to_response
class NumbersForm(forms.Form):
numbers = forms.ModelChoiceField(queryset=Zonas.objects.all())
def menuForm(request):
form = NumbersForm()
return render_to_response('hello.html', {'form': form})
hello.html:
<form action="" method="get">
<div class="field">
{{ form.as_p }}
</div>
<input type="submit" value="Submit">
</form>
</body>
</html>
You have several errors in your applications. Let's do the following:
You will need the following files in your testApp folder: models.py, views.py, forms.py. Now, inside models.py you will define model Zonas (pretty much as you have done)
#models.py
from django.db import models
class Zonas(models.Model):
name = models.CharField(max_length=30)
def __unicode__(self):
return self.name
Now, inside the forms.py file you will have this:
from testApp.models import Zonas
from django.forms import ModelForm
z = ((zona.name,zona.name) for zona in Zonas.objects.all())
class ZonasForm(ModelForm):
name = forms.CharField(max_length=30,widget=forms.Select(choices=z))
class Meta:
model = Zonas
Then, your views.py:
from testApp.forms import ZonasForm
from django.shortcuts import render_to_response
def menuForm (request):
if request.method = 'POST':
form = ZonasForm(request.POST)
if form.is_valid():
form.save()
else:
form = ZonasForm()
return render_to_response('hello.html', {'form':form})
There you have your form processed and everything.
Next, your hello.html:
<form action="" method="post">
{% csrf_token %}
<div class="field">
{{ form.as_p }}
</div>
<input type="submit" value="Submit">
</form>
</body>
All of this combined should work. You had some concept errors in your app definition, I hope this could help as a guide.
Related
I have a quiz form and when I want to save the answer the model does not store its question. I want to validate the form and save it when if form.is_valid (): I remove it and instead of AnswerForm I use the direct Answer model then it saves but not so. How to change it so that I can validate it and save it with the help of the form?
my code ->
models.py
from django.db import models
# Create your models here.
from django.core.exceptions import ValidationError
class Question(models.Model):
question=models.CharField(max_length=100)
answer_question=models.CharField(max_length=100, default=None)
def __str__(self):
return self.question
class Answer(models.Model):
questin=models.ForeignKey(Question, on_delete=models.CASCADE, related_name="questions")
answer=models.CharField(max_length=100,blank=True)
def __str__(self):
return str(self.questin)
forms.py
from django import forms
from django.contrib.auth.models import User
from django.core.exceptions import ValidationError
from django.forms import ModelForm
from .models import Question,Answer
class QuestionForm(forms.ModelForm):
class Meta:
model=Question
fields="__all__"
class AnswerForm(forms.ModelForm):
class Meta:
model=Answer
fields="__all__"
views.py
from django.shortcuts import render
from django.shortcuts import render, HttpResponse
from django.http import HttpResponseRedirect
from django.shortcuts import redirect
from .forms import QuestionForm,AnswerForm
from .models import Question,Answer
import random
from django.forms import modelformset_factory
def home(request):
form=QuestionForm
if request.method=='POST':
form=QuestionForm(request.POST)
if form.is_valid():
form.save()
return render(request, "question/base.html", {"form":form})
def ans(request):
questions=Question.objects.all()
form=AnswerForm()
if request.method=="POST":
if form.is_valid():
qu=request.POST["i_id"]
question_id=int(qu)
answ=AnswerForm(questin=question_id,answer=request.POST["answer"])
answ.save()
return render(request, "question/ans.html", {"form":form, "questions":questions})
ans.html
<!DOCTYPE html>
<html>
<head>
<title>question</title>
</head>
<body>
{% for i in questions %}
<form method="POST" required>
{% csrf_token %}
{{i}}
<input type="hidden" name="i_id" value="{{ i.id }}"/>
{% for a in form.answer %}
{{a}}
{% endfor %}
<input type="submit" name="sub">
</form>
{% endfor %}
</body>
</html>
I want to display to simple search Forms in a view.
forms.py:
from django import forms
from django.utils.translation import gettext_lazy as _
class Vehicle_Search_by_VIN(forms.Form):
vin = models.CharField(max_length=17)
first_registration_date = models.DateField()
class Vehicle_Search_by_Plate(forms.Form):
plate = models.CharField(max_length=7)
last_four_diggits_of_vin = models.DateField(max_length=4)
views.py:
from django.shortcuts import render
from django.views import View
from .forms import *
class VehicleSearch(View):
template = 'vehicle_search_template.html'
cxt = {
'Search_by_VIN': Vehicle_Search_by_VIN(),
'Search_by_Plate': Vehicle_Search_by_Plate()
}
def get(self, request):
return render(request, self.template, self.cxt)
my template-file:
<form class="by_vin" method="POST" action="">
{% csrf_token %}
{{ Search_by_VIN.as_p }}
<button name='action' value='login' type="submit">Suchen</button>
</form>
<form class="by_plate" method="POST" action="">
{% csrf_token %}
{{ Search_by_Plate.as_p }}
<button name='action' value='signup' type="submit">Suchen</button>
</form>
But as a result only the submit buttons are displayed in the view. Does anybody know why my forms aren't being rendered?
in views.py, i think, you are missing *args and **kwargs parameters in get() function
class VehicleSearch(View):
template = 'vehicle_search_template.html'
cxt = {
'Search_by_VIN': Vehicle_Search_by_VIN(),
'Search_by_Plate': Vehicle_Search_by_Plate()
}
def get(self, request, *args, **kwargs): # HERE
return render(request, self.template, self.cxt)
Update
By default, class-based views does only support a single form per view but you can counter this limitation with few options depending on your logic. refer to this thread Django: Can class-based views accept two forms at a time?
try to give full path in your template variable for e.g. if your app name is my_app then template = 'my app/vehicle_search_template.html'
I have hard time with such a easy thing (I guess).
My aim is to create two subpages with 2 different forms yet connected with the same user model:
/account/register.html - page only to manage registration (create user with login,email,password)
/account/questionnaire.html - page for UPDATING the same user information such as age,weight,height etc.
I've got 'POST' communicates in server log but nothing appears when I'm checking up django admin site.
models.py
from django.db import models
from django.contrib.auth.models import User
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
age = models.PositiveIntegerField(blank=False)
weight = models.PositiveIntegerField(blank=False)
height = models.PositiveIntegerField(blank=False)
forms.py
from django import forms
from django.core import validators
from django.contrib.auth.models import User
from account.models import UserProfile
class RegisterUserForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput())
class Meta():
model = User
fields = ('username','email','password')
class RegisterUserInfoForm(forms.ModelForm):
class Meta():
model = UserProfile
fields = ('age','weight','height')
views.py
from django.shortcuts import render
from account.forms import RegisterUserForm, RegisterUserInfoForm
from django.contrib.auth import authenticate, login, logout
from django.http import HttpResponseRedirect, HttpResponse
from django.urls import reverse
from django.contrib.auth.decorators import login_required
def register(request):
registered = False
if request.method == 'POST':
user_form = RegisterUserForm(data=request.POST)
if user_form.is_valid():
user = user_form.save()
user.set_password(user.password)
user.save()
registered = True
else:
print(user_form.errors)
else:
user_form = RegisterUserForm()
return render(request,'account/register.html',{
'user_form':user_form,
'registered':registered,
})
#login_required
def questionnaire(request):
if request.method == 'POST':
profile_form = RegisterUserInfoForm(request.POST, instance=request.user)
if profile_form.is_valid():
profile_form.save()
else:
print(profile_form.errors)
else:
profile_form = RegisterUserInfoForm(instance=request.user)
return render(request,'account/questionnaire.html',{
'profile_form':profile_form,
})
register.html
{% extends 'base.html' %}
{% block body_block %}
<div class="container">
<h1>Register</h1>
<form method="post">
{% csrf_token %}
{{ user_form.as_p }}
<input type="submit" name="btn btn-primary" value="Save">
</form>
</div>
{% endblock %}
questionnaire.html
{% extends 'base.html' %}
{% block body_block %}
<div class="container">
<h1>questionnaire</h1>
<form method="post">
{% csrf_token %}
{{ profile_form.as_p }}
<input type="submit" name="" value="Save">
</form>
</div>
{% endblock %}
Your view doesn't receive a POST request because you didn't provide an action attribute to your form tag. So, your form passes your POST request nowhere. Try it like this:
<form action="" method="post">
{% csrf_token %}
{{ user_form.as_p }}
<input type="submit" name="btn btn-primary" value="Save">
</form>
Also, you should definitely check django's built-in generic views: CreateView and UpdateView. They serve exactly for such purposes and makes almost everything for you.
In my Django app in a Createview class it never enters the is_valid(): statement and I can not seem to find any errors:
models.py
from django.db import models
from django.core.urlresolvers import reverse
from django.contrib.auth.models import User
from django.conf import settings
from .validators import validate_file_extension
import zipfile
class Post(models.Model):
title = models.CharField(max_length=140)
body = models.TextField(max_length=250)
date = models.DateTimeField(auto_now=True, auto_now_add=False)
album_image = models.FileField(validators=[validate_file_extension])
user = models.ForeignKey(User, default=1)
face = models.IntegerField(default=1)
def get_absolute_url(self):
return reverse('photos:detail',kwargs={'pk':self.pk})
def __str__(self):
return self.title
views.py
This is my view folder that contains a list view a detailed view and create view. Although the form doesnt pass the valid test, it still gets uploaded and is viewable by the user
from django.http import Http404
from django.http import HttpResponse
from django.shortcuts import render, get_object_or_404
from django.core.urlresolvers import reverse
from .forms import PostForm
from .models import Post
from django.contrib.auth.models import User
from django.template import loader
from django.views import generic
from django.views.generic.edit import CreateView
import cognitive_face as CF
import json
class IndexView(generic.ListView):
template_name='photos/post.html'
def get_queryset(self):
return Post.objects.filter(user=self.request.user)
class DetailView(generic.DetailView):
model = Post
template_name = 'photos/detail.html'
class PostCreate(generic.CreateView):
form = PostForm()
model = Post
if form.is_valid():
print('valid')
instance = form.save(commit=False)
username = form.cleaned_data['username']
album_image = form.cleaned_data['album_image']
instance.save()
if not form.is_valid():
print('not')
post_form.html
<html>
<body>
{% if request.user.is_authenticated%}
<h3>Hello {{request.user.username}}, please upload your image as either a .JPEG, .GIF or .PNG</h3>
{% endif %}
<div class="container-fluid">
<div class="row">
<div class="col-sm-12 col-md-7">
<div class="panel panel-default">
<div class="panel-body">
{% if request.user.is_authenticated %}
<form class="form-horizontal" role="form" action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{form.as_p}}
{{ form.errors }}
{{ form.non_field_errors }}
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-success">Submit</button>
</div>
</div>
</form>
{% else %}
<p>You must be logged in to upload a file</p>
{% endif %}
</div>
</div>
</div>
</body>
</html>
urls.py
from django.conf.urls import url, include
from django.views.generic import ListView, DetailView
from photos.models import Post
from . import views
app_name = 'photos'
urlpatterns = [
url(r'^$',views.IndexView.as_view(), name='index'),
url(r'^(?P<pk>[0-9]+)/$',views.DetailView.as_view(), name='detail'),
url(r'post/add/$', views.PostCreate.as_view(), name='post-add'),
]
You are writing function based view code inside a class based view, which is incorrect.
You shouldn't need to instantiate the form, or manually check whether it is valid. Just set form_class for the view, then override form_valid or form_invalid if you need to change the behaviour when the form is valid or invalid. Since you have {{ form.errors }} in your template, it should show any errors when you submit the form.
class PostCreate(generic.CreateView):
form_class = PostForm
model = Post
See the docs on form handling with class based views for more information. You might find it easier to write a function based view to begin with, since the flow of the code is easier to follow.
I'm trying to upload csv through django but it's not working..
Code
Views.py
from django.shortcuts import render_to_response
from forms import UploadForm
from django.http import HttpResponseRedirect
def create(request):
if request.method == 'POST':
form = UploadForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return HttpResponseRedirect('/success/url/')
else:
form = UploadForm()
return render_to_response('upload.html', {'form': form})
Url.py
urlpatterns = patterns('',
(r'^$', create),
#url(r'^articles/create/$', create, name='done'),
url(r'^articles/create/$', 'article.views.create'),
)
models.py
from django.db import models
from time import time
def get_upload_file_name(instance, filename):
return "uploaded_files/%s_%s" % (str(time()).replace('.','_'), filename)
class Article(models.Model):
file = models.FileField(upload_to=get_upload_file_name)
Forms.py
from django import forms
from models import Article
class UploadForm(forms.ModelForm):
class Meta:
model = Article
html file
{% csrf_token %}
{{form.as_p}}
Your template needs to be:
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" />
</form>
See the binding uploaded files to a form section in the documentation.