Why does the "engine" capitalize this variable. Can it be hidden? - python

The view:
def GRID_ServerDropDownSearch(request):
if 'r' in request.GET and request.GET['r']:
r = request.GET['r']
servers = SERVERS.objects.get(name=r)
drives = servers.drives_set.all()[0:]
memory = servers.memory_set.all()[0:]
return render_to_response('GRID_ServerDropDownSearchResults.html',
{'servers':servers, 'query':r, 'drives':drives, 'memory':memory})
else:
return render_to_response('GRID_search_form.html', {'error': True})
The form:
class ServerDropDownForm(forms.Form):
r = forms.ModelChoiceField(queryset = SERVERS.objects.all(), required=False)
The template:
<div>
<form action="/ServerDropDownSearch/" method="GET">
{{ form.as_table }}
<input type = "Submit" value = "Submit">
</form>
</div>
The resulting drop-down form works flawlessly. However, immediately to the left of the drop-down list is an "R" (capital r). I know it has to do with the "r" specified in the above code. (If I replace each incidence of r with, say, z then a "Z" appears). However:
WHY does it get capitalized ? Is this just the default case specified in the engine ?
How can I hide that "R" so that, instead, it can indicate "Select A Server", or something more descriptive.
Thanks in advance.

Django derives the label for a form field from the corresponding variable name, but "humanizes" it. For example, a field called my_variable would translate to "My variable".
The simplest way to fix this would be to give a more human-readable name to the field:
server = forms.ModelChoiceField(queryset = SERVERS.objects.all(), required=False)
However, you can also pass a string to use as the label via the form field's label parameter:
r = forms.ModelChoiceField(queryset = SERVERS.objects.all(), required=False, label='Select a server')

Related

How to make foreign key accept field value instead of its id in django?

I have created a checkbox for content filtering of products based on category.So when the user clicks on any checkbox only the books with that category should be shown.In the view I am passing the value of checkbox field(category name) obtained from the template but upon filtering, the foreign key is expecting pk(id) instead of field value.I am getting error like this,invalid literal for int() with base 10: '<category name>'.So is it possible to make foreign key accept value instead of id?
Models.py,
class Add_cat(models.Model):
category = models.CharField("Name",max_length=25,unique=True)
def __unicode__(self):
return u'{0}'.format(self.category)
class Add_prod(models.Model):
book = models.CharField("Book Name",max_length=40)
author = models.CharField("Author",max_length=30)
price = models.PositiveIntegerField("Price")
image = models.ImageField(upload_to='images',null=True)
cat = models.ForeignKey(Add_cat,on_delete=models.PROTECT)
Template file,
{% for i in products %}
<input type="checkbox" name="cat_name" value="{{i.cat}}">{{i.cat}}<br>
{% endfor %}
Views.py,
def welcome_user(request):
if 'cat_name' in request.GET:
filter_category = request.GET.get('cat_name')
my_products = Add_prod.objects.filter(cat__in = filter_category)
context = { "products":my_products}
else:
my_products = Add_prod.objects.all()
context = { "products":my_products}
return render(request,"welcome-user.html",context)
You can check in the category field itself:
my_products = Add_prod.objects.filter(cat__category__in=filter_category)
Have a look at the documentation on how this works.
Above, is only applicable if filter_category is a list. If it is a string you can filter like following:
my_products = Add_prod.objects.filter(cat__category=filter_category)
There are two things wrong with your code
You need to look up the field rather than the foreign key
By using __in you are looking the category is equal to any one of the characters in the filter_category.
Hence to fix, use the field lookup and remove the __in
Add_prod.objects.filter(cat__category=filter_category)
You can try this,it will help you:
Add_prod.objects.filter(cat__category = filter_category)

Creating a simple django form

I am new to django and and I'm trying to use forms.I want to create a form with two CharFields. Here is where I am so far -
forms.py
from django import forms
class NameForm(forms.Form):
key = forms.CharField(label='Enter Key:', max_length=2)
value = forms.CharField(label='Enter Value:', max_length=4)
template.html
<form action="/new-page/" method="GET">
{{ form }}
<input type="submit" value="Submit" />
</form>
What I want is to take the data in this form and simply use that data in my function myfunc
views.py
def myfunc(request,id):
key = request.GET.get('key')
value = request.GET.get('value')
where id is the id of the page where the form appears like so url/places/1/
I want the action to send the id and the key,value pair to the function to use on submit.Validation is not required. Can someone help me understand the concept here.
Your views.py should look like:
def myfunc(request, id):
form = NameForm(request.GET or None)
if form.is_valid():
key = form.cleaned_data['key']
value = form.cleaned_data['value']
# do something with key and value

Get value of a form input by ID python/flask

How do you get the actual value of the input id after you send it in Flask?
form:
<form action="" method="post">
<input id = "number_one" type="text" name="comment">
<input type="submit" value = "comment">
</form>
like, what I am trying to say is when the form is sent (i.e. when you do this):
request.form.get("comment")
the value of the text field is passed. What I can't figure out is how to get the value of the id.
So, when the form is sent we could then tell from which form the info was coming from, because each form has a unique id. In this case the id is number_one.
So, how do we go about getting the actual literal value of the id and not the text input?
You can't. The id value is not part of the form data set sent by the browser.
If you need to identify the field, you'll have to either add the id to the input element name, or if the id is generated by Javascript code, perhaps store the information in an extra hidden field.
Adding the id to the name could be done with a delimiter perhaps:
<input id = "number_one" type="text" name="comment.number_one">
which would require you to loop over all form keys:
for key is request.form:
if key.startswith('comment.'):
id_ = key.partition('.')[-1]
value = request.form[key]
There is a one way to identify the fields and also multiple forms together....
use this
<input value = "1" type="hidden" name="my_id">
so at your view file you can retrieve this value.
my_id = request.form.get("my_id","")
print my_id
your output will be
1
you can also do this...
my_id = request.form.get("my_id","")
if my_id == "1":
** for example **
value = request.form.get("any_parameter_of_form","")

How to create dynamic forms in Django? [duplicate]

I'm working on something like an online store. I'm making a form in which the customer buys an item, and she can choose how many of these item she would like to buy. But, on every item that she buys she needs to choose what its color would be. So there's a non-constant number of fields: If the customer buys 3 items, she should get 3 <select> boxes for choosing a color, if she buys 7 items, she should get 7 such <select> boxes.
I'll make the HTML form fields appear and disappear using JavaScript. But how do I deal with this on my Django form class? I see that form fields are class attributes, so I don't know how to deal with the fact that some form instance should have 3 color fields and some 7.
Any clue?
Jacob Kaplan-Moss has an extensive writeup on dynamic form fields:
http://jacobian.org/writing/dynamic-form-generation/
Essentially, you add more items to the form's self.fields dictionary during instantiation.
Here's another option: how about a formset?
Since your fields are all the same, that's precisely what formsets are used for.
The django admin uses FormSets + a bit of javascript to add arbitrary length inlines.
class ColorForm(forms.Form):
color = forms.ChoiceField(choices=(('blue', 'Blue'), ('red', 'Red')))
ColorFormSet = formset_factory(ColorForm, extra=0)
# we'll dynamically create the elements, no need for any forms
def myview(request):
if request.method == "POST":
formset = ColorFormSet(request.POST)
for form in formset.forms:
print "You've picked {0}".format(form.cleaned_data['color'])
else:
formset = ColorFormSet()
return render(request, 'template', {'formset': formset}))
JavaScript
<script>
$(function() {
// this is on click event just to demo.
// You would probably run this at page load or quantity change.
$("#generate_forms").click(function() {
// update total form count
quantity = $("[name=quantity]").val();
$("[name=form-TOTAL_FORMS]").val(quantity);
// copy the template and replace prefixes with the correct index
for (i=0;i<quantity;i++) {
// Note: Must use global replace here
html = $("#form_template").clone().html().replace(/__prefix_/g', i);
$("#forms").append(html);
};
})
})
</script>
Template
<form method="post">
{{ formset.management_form }}
<div style="display:none;" id="form_template">
{{ formset.empty_form.as_p }}
</div><!-- stores empty form for javascript -->
<div id="forms"></div><!-- where the generated forms go -->
</form>
<input type="text" name="quantity" value="6" />
<input type="submit" id="generate_forms" value="Generate Forms" />
you can do it like
def __init__(self, n, *args, **kwargs):
super(your_form, self).__init__(*args, **kwargs)
for i in range(0, n):
self.fields["field_name %d" % i] = forms.CharField()
and when you create form instance, you just do
forms = your_form(n)
it's just the basic idea, you can change the code to whatever your want. :D
The way I would do it is the following:
Create an "empty" class that inherits from froms.Form, like this:
class ItemsForm(forms.Form):
pass
Construct a dictionary of forms objects being the actual forms, whose composition would be dependent on the context (e.g. you can import them from an external module). For example:
new_fields = {
'milk' : forms.IntegerField(),
'butter': forms.IntegerField(),
'honey' : forms.IntegerField(),
'eggs' : forms.IntegerField()}
In views, you can use python native "type" function to dynamically generate a Form class with variable number of fields.
DynamicItemsForm = type('DynamicItemsForm', (ItemsForm,), new_fields)
Pass the content to the form and render it in the template:
Form = DynamicItemsForm(content)
context['my_form'] = Form
return render(request, "demo/dynamic.html", context)
The "content" is a dictionary of field values (e.g. even request.POST would do).
You can see my whole example explained here.
Another approach: Rather than breaking the normal field initialization flow, we can override fields with a mixin, return an OrderedDict of dynamic fields in generate_dynamic_fields which will be added whenever its set.
from collections import OrderedDict
class DynamicFormMixin:
_fields: OrderedDict = None
#property
def fields(self):
return self._fields
#fields.setter
def fields(self, value):
self._fields = value
self._fields.update(self.generate_dynamic_fields())
def generate_dynamic_fields(self):
return OrderedDict()
A simple example:
class ExampleForm(DynamicFormMixin, forms.Form):
instance = None
def __init__(self, instance = None, data=None, files=None, auto_id='id_%s', prefix=None, initial=None,
error_class=ErrorList, label_suffix=None, empty_permitted=False, field_order=None,
use_required_attribute=None, renderer=None):
self.instance = instance
super().__init__(data, files, auto_id, prefix, initial, error_class, label_suffix, empty_permitted, field_order,
use_required_attribute, renderer)
def generate_dynamic_fields(self):
dynamic_fields = OrderedDict()
instance = self.instance
dynamic_fields["dynamic_choices"] = forms.ChoiceField(label=_("Number of choices"),
choices=[(str(x), str(x)) for x in range(1, instance.number_of_choices + 1)],
initial=instance.initial_choice)
return dynamic_fields

Django fill up ChoiceField - Select html options

I am facing problem filling my select options using django forms. Even though I define choices, I don't see any choices.
My form in .py file:
class SignupForm(forms.Form):
countrySignup = forms.ChoiceField( required = True,
widget = forms.Select( choices = ('United States', 'Jordan') ))
my html template has the following:
<p>
<label for="countrySignup" class="youcountry" data-icon="">Your Country </label> </br>
{{ signupForm.countrySignup }}
{{ signupForm.countrySignup.errors }}
</p>
and of course my view has the following code to pass the variable to template:
def myView(request):
#
# create the unbinded forms for registration
#
if request.method == 'GET':
signupForm = regForms.SignupForm()
return render(request,
"login.html",
{'loginForm': loginForm,
'signupForm' : signupForm })
What am I missing because I don't see any options in my select , it remains empty
I missed the documentation that choices needs to be a list of tuples with 2 elements each.
choices:
An iterable (e.g., a list or tuple) of 2-tuples to use as choices for this field. This argument accepts the same formats as the choices argument to a model field. See the model field reference documentation on choices for more details.**
this solved it:
countrySignup = forms.ChoiceField( choices = [('PS', 'Palestine'),
('JD', 'Jordan')] )

Categories

Resources