Django: Initial Value for Form - django

I want to show an initial value in the form. At runtime no errors occurs, the field stays empty. Why isn't it showing the value?
views.py:
def mieteinheit(request, wohnungsgruppenname):
if request.method == 'POST':
#...
else:
form = WohnungseinheitenForm(request.POST or None,initial={'ort':'Hof'})
template = loader.get_template('Immo/user/mieteinheit.html')
context = {"wohnungsgruppenname":wohnungsgruppenname,"form": form}
return HttpResponse(template.render(context,request))
.html-File:
<input class="form-control" id="{{ form.ort.auto_id }}" name="ort" type="text" >
Form.py:
class WohnungseinheitenForm(forms.ModelForm):
ort = forms.CharField(required=True,max_length=100)

In forms.py, add initial property to the ort field.
ort = forms.CharField(required=True,max_length=100,initial='Hof')

Related

Validation for current user

How to realize checking 'name' for current user in forms.py in ValidationError('Same name already added, change name').
views.py
#login_required
def main_page(request):
form = URL_listForm(request.POST)
if request.method == "POST":
if form.is_valid():
name = form.cleaned_data['name']
if URL_list.objects.filter(user=request.user, name=name).exists():
return HttpResponse('Same name already added, change name')
new_post = form.save(commit=False)
new_post.user = request.user
new_post.save()
return HttpResponse("Data added")
return render(request, 'link/main.html', {'form': form})
If you want validate in database
#-------ADDED CODE
data_tmp = """SELECT count(*) from jobtest WHERE link = %s""", (line)
data_tmp = cur.fetchall()
#-------END ADDED CODE
if (data_tmp == 0 ) :
Not exist
add form with name
<input type="text" id="projectName" size="40" placeholder="Spot your project files">
<input type="button" id="spotButton" value="Spot">
when press post button and action to api you can get value in input field using request.form['Name']
if you want send data from server code to html
return render_template('index.html', data=userinfo)
and render as
{% userinfo %}

Unique=True in Form not throwing any error

I'm entering a duplicate value (already saved in another instance of the same model) in my form to test the unique=True attribute. form.is_valid() returns 'False', as expected, but I don't receive any prompt in the template. Shouldn't I get prompted something like "obj with this value already exists"? The page simply reloads... What am I missing?
forms.py
def update_route(request, pk):
instance = Route.objects.get(id=pk)
if request.method == "POST":
form = RouteForm(request.POST)
if form.is_valid():
data = form.cleaned_data
instance.name = data['name']
instance.priority = data['priority']
instance.url = data['url']
return redirect('campaigns:routes_list')
form = RouteForm(instance=instance)
context= {
'form': form,
}
return render(request, "campaigns/route_form.html", context)
models.py
class Route(models.Model):
name = models.CharField(max_length=48)
priority = models.SmallIntegerField(choices=PRIORITY_LEVEL, default=0, unique=True)
url = models.URLField()
Template
<form method="post" action="">
{% csrf_token %}
{{form.as_p}}
<input type="submit" value="Submit">
</form>
Your update_route() view handles the condition in which the submitted form is valid (form.is_valid()), but not the condition in which the form is invalid.
The errors you are looking for are stored in the form object that you created with RouteForm(request.POST). The errors are generated when the is_valid() method is called.
This form object needs to be added to the context dict and rerendered to the user for the errors to surface. But your code currently overwrites that object with form = RouteForm(instance=instance), so the POST data and the related errors disappear.
One solution could be to handle it in the conditional statement:
if form.is_valid():
...
else:
context = {'form': form}
return render(request, "campaigns/route_form.html", context)
Another solution could be to create a conditional statement for GET requests, for example:
elif request.method == 'GET':
form = RouteForm(instance=instance)

Django: disable error messages for required field on initial form view?

I've got a Django form that looks like this and allows users to make a choice:
class ChoiceForm(forms.Form):
candidate = forms.CharField(widget=forms.HiddenInput)
CHOICES = ((True, 'Yes',), (False, 'No',))
choice_field = forms.ChoiceField(choices=CHOICES, required=True,
widget=forms.RadioSelect)
The template looks like this:
<form id="pledge" action="/pledge" method="post">
{% csrf_token %}
{{ form.non_field_errors }}
<div class="fieldWrapper">
{{ form.choice_field.errors }}
{{ form.choice_field }}
</div>
{{ form.candidate }}
<div class="form-actions">
<button type="submit" class="btn btn-primary" value="Submit">Submit your response</button>
</div>
</form>
My view is like this:
def pledge(request, candidate_hashkey=None):
candidate = None
if request.method == 'POST':
# process input
else:
candidate = get_object_or_404(Candidate, pledge_hashkey=candidate_hashkey)
form = PledgeForm({'candidate': candidate_hashkey})
context = {
'form': form,
'candidate': candidate
}
return render(request, 'frontend/pledge.html', context)
The problem is that on the initial GET view, before the user chooses anything, the form appears with an error at the top: "This value is required".
How can I disable this for the initial view?
For the GET request, you could use initial. This means the form is unbound so it won't be validated.
if request.method == 'POST':
# process input
else:
candidate = get_object_or_404(Candidate, pledge_hashkey=candidate_hashkey)
form = PledgeForm(initial={'candidate': candidate_hashkey})
However, it might be easier to remove the candidate field from the form entirely. To do this, you'll have to keep the hash in the URL (instead of action="/pledge" which appears to remove it).
class ChoiceForm(forms.Form):
CHOICES = ((True, 'Yes',), (False, 'No',))
choice_field = forms.ChoiceField(choices=CHOICES, required=True,
widget=forms.RadioSelect)
Then set the candidate field when you save the form:
if request.method == 'POST':
if form.is_valid():
obj = form.save(commit=False)
candidate = get_object_or_404(Candidate, pledge_hashkey=candidate_hashkey)
obj.candidate = candidate
obj.save()
...
You are bounding PledgeForm with data that's why you are seeing the error messages:
form = PledgeForm({'candidate': candidate_hashkey})
You should not bound the form with data:
form = PledgeForm()
P.S Although you say your form is ChoiceForm but in view you are using PledgeForm, but my answer might give you hints anyway.

How to retain select option value after submit in django?

I have created select tag with four option values(1,2,3,4).When I select 4 and press submit it changes back to 1.Select option contains quantity of the product needed for the user.So how to retain option value after pressing submit button.I tried like this,after I press submit button value changes back to 1.Is there any way to overcome this problem?
My template file,
<label for="quantity">Quantity</label>
<select id="quantity" name="quantity">
<option value="1" {% if quantity == '1' %}selected{% endif %}>1</option>
<option value="2" {% if quantity == '2' %}selected{% endif %}>2</option>
<option value="3" {% if quantity == '3' %}selected{% endif %}>3</option>
<option value="4" {% if quantity == '4' %}selected{% endif %}>4</option>
</select>
<input type="submit" value="Buy"/>
UPDATE:
forms.py,
class SortForm(forms.Form):
RELEVANCE_CHOICES = (
(1,'1'),(2, '2'),(3,'3'), (4,'4'),(5,'5'),
)
sort = forms.ChoiceField(choices = RELEVANCE_CHOICES,label='Quantity')
views.py,
from .forms import SortForm
#csrf_protect
def buy_book(request,pk):
form = SortForm(request.POST or None)
my_products = Add_prod.objects.filter(pk=pk)
#Add_prod is the model class name
context = {"products":my_products}
if request.POST.get('quantity'):
for i in my_products:
rate= i.price
#price is the column name in the model class
u_quantity = request.POST.get('quantity')
Quantity=int(u_quantity)
total = rate*Quantity
context = {
"products":my_products,
"Total":total,
"form": form
}
return render(request,"buy_book.html",context)
In the template file I added this line,
{{form.as_p}}
Now I am getting blank output.I think the form is not recognising in the template.
The problem here that your template is just showing data, it doesn't know anything about state. So if you want to achieve this kind of behavior you need to supply all required data from backend. Also as #solarissmoke mentioned you should use django forms.
for exmaple(Pseudo code below)
def my_view(request):
if request.method == 'POST':
form = MyForm(request.data)
if form.is_valid():
form.save()
redirect(reverse('myview'))
else:
form = MyForm(instance) # <- instance is object with previously saved data
return render(request, 'my_template.html' , {'form': form})
Second Part
def buy_book(request,pk):
form = SortForm(request.POST or None)
my_products = Add_prod.objects.filter(pk=pk)
#Add_prod is the model class name
context = {"products":my_products}
if request.POST.get('quantity'):
for i in my_products:
rate= i.price
#price is the column name in the model class
u_quantity = request.POST.get('quantity')
Quantity=int(u_quantity)
total = rate*Quantity
context = {
"products":my_products,
"Total":total,
"form": form # <- here is problem
}
return render(request,"buy_book.html",context)
You are adding form to context inside if request.method == 'POST'. It should like this
def buy_book(request,pk):
form = SortForm(request.POST or None)
my_products = Add_prod.objects.filter(pk=pk)
#Add_prod is the model class name
context = {"products":my_products, 'form': form} # <- here
if request.POST.get('quantity'):
for i in my_products:
rate= i.price
#price is the column name in the model class
u_quantity = request.POST.get('quantity')
Quantity=int(u_quantity)
total = rate*Quantity
context = {
"products":my_products,
"Total":total,
}
return render(request,"buy_book.html",context)
In your view, you only ever add the form to the context data if there is a quantity in the post data, you should add this to the context regardless since it is required for your view.
You should also actually use the form, so instead of checking the post data, check the form for validity and then use its cleaned data.
def buy_book(request,pk):
form = SortForm(request.POST or None)
my_products = Add_prod.objects.filter(pk=pk)
#Add_prod is the model class name
context = {"products":my_products,
'form': form}
if form.is_valid():
for i in my_products:
rate= i.price
#price is the column name in the model class
u_quantity = form.cleaned_data.get('sort', 0)
Quantity=int(u_quantity)
total = rate*Quantity
context['total'] = total
return render(request,"buy_book.html",context)
'int' object is not iterable
Probably because your sort field isn't a list of tuples
choices = [(i, i) for i in range(1,6)]

django field/widget for multiple values

I seriously can't figure out how to manage to do this.
I would like to use django forms to validate the following (unknown number of aname):
<input type="hidden" name="aname" value="someJSONdump1"/>
<input type="hidden" name="aname" value="someJSONdump2"/>
<input type="hidden" name="aname" value="someJSONdump3"/>
<input type="hidden" name="aname" value="someJSONdump4"/>
and on the django side, I'm calling:
form = myforms.MyForm(request.POST, request.FILES)
if (form.is_valid()):
# do something
else:
# redisplay the form
How do I define MyForm to allow me to validate each aname and also, when in error, the widget to redisplay the above <input>s?
I can't figure out how to use the MultiValueField or even if it's the right thing to use. It seems to be a solution when you know how many fields you have?
Using clean_aname() in the form is no help as self.cleaned_data.get('aname') is only the last value.
Without the form, I would use something like request.POST.getlist('aname'), but I would like to avoid this if I can do it with django.forms.
Thanks for your help.
EDIT
I've left aside that I was defining more fields from a ModelForm. I think this might have some effects with formset. Here is where I am at... Is this solution considered to be "Django forms" compatible?
class MyField(forms.Field):
widget = MyWidget
def to_python(self, value):
if (isinstance(value, basestring)):
value = [value]
return [json.loads(v) for v in value]
class MyForm(forms.ModelForm):
class Meta:
model = models.MyModel
aname = MyField()
def clean(self):
cleaned_data = super(MyForm, self).clean()
cleaned_data['aname'] = self.fields['aname'].clean(self.data.getlist('aname'))
return cleaned_data
Now, I have to define MyWidget to allow me to display a list of <input type="hidden">, but I would like to know if this solution sound acceptable. Maybe I could have done this in clean_aname() too.
You could try implementing this using a set of forms (called formsets within Django), in which each form would be an instance of the validation form you want. For instance,
class ValidationForm(forms.Form):
aname = forms.CharField()
def clean_aname(self):
aname = self.cleaned_data['aname']
# TODO validate aname
return aname
def save(self, commit=False):
# TODO implement this form's save logic
return 'It works!'
For creating a set of those forms (see formset documentation), do:
from django.forms.formsets import formset_factory
ValidationFormSet = formset_factory(ValidationForm)
On your view, use the ValidationFormSet for receiving the data:
def my_view(request):
if request.method == 'POST':
form = ValidationFormSet(request.POST, request.FILES)
if form.is_valid():
# All anames were validated by clean_aname
results = form.save()
for r in results:
print r # Should print 'It works!'
else:
form = ValidationFormSet()
return <your_result>
You can pass multiple forms to your view using prefix, like this:
jsondumplist = ['jsondump1', 'jsondump2', 'jsondump3', 'jsondump4'....]
if request.method == 'POST':
forms = [YourForm(request.POST, prefix=x) for x in jsondumplist]
for f in forms:
if f.is_valid():
f.save()
else:
forms = [YourForm(prefix=x) for x in jsondumplist]
YourForm could have just the single field you are interested in, or several.
class YourForm(forms.Form):
aname = forms.CharField(widget=forms.HiddenInput())
Then, your template will look something like this:
{% for form in forms %}
{% for field in form %}
{{ field }}
{% endfor %}
{% endfor %}