I'm new in python/django and i have a problem, i'm trying to use checkbox filtering in my html table and i don't really know how to do it.
This is what i have now
I want to add these
models.py
class Tags(models.Model):
tag_frequency = models.CharField(max_length=250)
views.py
#login_required(login_url='/login/')
def index(request):
title = 'Tags'
all_tags = Tags.objects.all()
return render(request, 'tag/index.html' ,{'all_tags':all_tags, 'title':title})
How do i use filter with these, i tried something like this but doesn't work:
LF = 125 - 134.2 KHz
HF = 13.56 MHz
UHF = 860 - 960 MHz
LF = Tags.objects.filter(tag_frequency__gt=125, tag_frequency__lt=134.2)
In order to make your query works, you have to change your field to FloatField:
class Tags(models.Model):
tag_frequency = models.FloatField(default=0.00, null=True, blank=True)
Set null, blank and default values based on your needs.
Then, put your checkboxes (or radio inputs) in your html form like this:
<form action="" method="post">
<!-- other form fields and csrf_token here -->
<div><label for="input_lf"><input type="checkbox" name="is_lf" id="input_lf"> LF</label></div>
<div><label for="input_hf"><input type="checkbox" name="is_hf" id="input_hf"> HF</label></div>
<div><label for="input_uhf"><input type="checkbox" name="is_uhf" id="input_uhf"> UHF</label></div>
<input type="submit" value="Submit"/>
</form>
Then in your view, you can try something like this:
def form_view(request):
if request.method == 'POST':
# these strings come from HTML Elements' name attributes
is_lf = request.POST.get('is_lf', None)
is_hf = request.POST.get('is_hf', None)
is_uhf = request.POST.get('is_uhf', None)
# Now make your queries according to the request data
if is_lf:
LF = Tags.objects.filter(tag_frequency__gt=125, tag_frequency__lt=134.2)
if is_hf:
# another query here
# and rest of your view
Related
I'm building a simple web app where users can log new entries that have a name (CharField) and a date.
By default, the date is set to the current date:
class EntryForm(forms.Form):
entry_name = forms.CharField(label='New Entry', max_length=100)
entry_date = forms.DateField(initial=datetime.date.today, widget=forms.widgets.DateInput(attrs={'type': 'date'}))
If users select a different date and add an entry with that date, I want the selected date to persist as new initial value when the page reloads.
I know there are a lot of related questions on setting initial values dynamically, but unfortunately, I still could achieve setting an initial value dynamically.
My view with the form looks like this:
#login_required
def index(request):
if request.method == 'POST':
form = EntryForm(request.POST)
if form.is_valid():
# get the label name and strip and convert to lower before saving it
entry_name = form.cleaned_data['entry_name'].strip().lower()
entry_date = form.cleaned_data['entry_date']
entry = Entry.objects.create(name=entry_name, date=entry_date, owner=request.user)
return HttpResponseRedirect(reverse('app:index'))
else:
form = EntryForm()
# other, unrelated stuff stuff ...
context = {
'form': form,
}
return render(request, 'app/index.html', context)
Even setting the initial value of a form field to a fixed value inside the view's else branch didn't work. I tried EntryForm(initial={'entry_name': 'test'}) (also for entry_date) without success. Also form.fields['entry_name'].initial = 'test', which didn't work either. In both cases, the from's entry_name remained empty when reloading the page.
What's the problem? How can I set the initial value in the form (neither for name nor for date)?
Is it somehow because the form is still unbounded?
If setting the initial value in the view worked, I think I could simply set it when the date is entered and it should stay when the page is reloaded since I pass the form (with the adjusted initial value) in the context dict when rerendering the page.
Edit: This is how I render my form in the template:
<div class="input-group">
<input type="text" class="form-control" id="{{ form.entry_name.id_for_label }}" name="{{ form.entry_name.html_name }}" aria-label="new entry field">
{{ form.entry_date }}
<div class="input-group-append">
<button type="submit" class="btn btn-primary">Add</button>
</div>
</div>
Oh, I think I didn't test correctly. In fact, setting
form = EntryForm(initial={'entry_date': '2020-12-12'})
inside my view does work fine and the date gets initialized as configured.
I guess, I just tried passing a datetime.date before or tested with initializing entry_name, but that didn't work because of how I render entry_name in the template.
To persist the previously entered date, I added an optional argument init_date to my index view, which is set according to the previously entered date:
def index(request, init_date=datetime.date.today()):
if request.method == 'POST':
form = EntryForm(request.POST)
if form.is_valid():
entry_name = form.cleaned_data['entry_name'].strip().lower()
entry_date = form.cleaned_data['entry_date']
entry = Entry.objects.create(name=entry_name, date=entry_date, owner=request.user)
return HttpResponseRedirect(reverse('app:index_with_date', args=[entry_date]))
else:
form = EntryForm(initial={'entry_date': init_date})
For that, I added another URL pattern:
path('add/<entry_name>/<yyyymmdd:entry_date>/', views.add_entry, name='add_entry_with_date'),
With the following date converter:
class DateConverter:
regex = '\d{4}-\d{2}-\d{2}'
def to_python(self, value):
return datetime.datetime.strptime(value, '%Y-%m-%d')
def to_url(self, value):
return value
register_converter(DateConverter, 'yyyymmdd')
I have a Django form NameForm. I am attempting to iterate over an array of values and, for each value, have an option to display the same form. The only thing that should change with the form submission should be the associated value to which the form is displayed next to.
This becomes much clearer with an example. For some array [1,2,3] we should display:
We can then click on any open form icon, fill out the NameForm form. The resultant information, including the form_id (in this case 1, 2, or 3) should be returned to forms.py. How can I fetch the form_id variable from an instance of NameForm in index.py?
My (hacky) attempt can be found below. The problem is I don't know how to access the form_id variable I created in the NameForm object.
forms.py
class NameForm(forms.Form):
form_id = None
your_name = forms.CharField(label='Your name', max_length=3)
views.py
def index(request):
if request.method == 'POST':
form = NameForm(request.POST)
form_id = form.form_id # The problem line, as form_id is always None
if form.is_valid():
return HttpResponse( \
' '.join((str(form.cleaned_data['your_name']),form_id ))\
) #Throws TypeError as can't join None and string
else:
forms = []
vals = [1,2,3]
for val in vals:
form = NameForm()
form.form_id = val
forms.append(form)
return render(request, 'post/index.html', {'forms': forms})
index.html
{%for form in forms%}
{{form.form_id}}
<button class="button" onclick="openForm()">Open Form</button>
<div class="myForm">
<form class="form-container" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit">
<button class="button" onclick="closeForm()">Cancel</button>
</form>
</div>
</br>
{%endfor%}
In Django Form or Django Model, when you set a field's value to None, it is assumed that you want to ignore said field. This is helpful when creating a model that inherits from another model and you want to remove some unnecessary fields.
If you want to set value for a field on Form creation, you should pass it into __init__ method. E.g:
class NameForm(forms.Form):
form_id = forms.IntegerField(widget=forms.HiddenInput())
your_name = forms.CharField(label='Your name', max_length=3)
def __init__(self, form_id, *args, **kwargs):
self.fields['form_id'].initial = form_id
Alternatively, instead of overriding the __init__ method, you can set an initial value for form_id when you create an instance of NameForm. For example:
vals = [1,2,3]
forms = [NameForm(initial={'form_id': val}) for val in vals]
I'm using using Django forms to collect information from users. But when I change between pages I want to use one of the value from url to be displayed in a from in the next page.
Example.
I have url for checking out a book like
http://127.0.0.1:8000/checkout/780374157067
780374157067 is the ibn of the book
Next page has a form where I get the ISBN and card id of the user. How to fill the form with the ISBN and show the form to user. rather than the user giving the ISBN again.
ISBN Filed should be pre filled with thw isbn in URL.
HTML :
<div class ="col-md-3">
<form method='POST' action=''>{%csrf_token%}
{{template_form | crispy}}
<input class="btn btn-lg btn-primary" type='submit'
value='Submit'/>
</form>
</div>
Forms.py
class loansform(forms.Form):
Isbn = forms.IntegerField()
Card_id = forms.IntegerField()
def clean_Isbn(self):
isbn = self.cleaned_data.get("Isbn")
isbn_string = str(isbn)
if len(isbn_string) != 13:
raise forms.ValidationError("Enter a valid ISBN-13")
return isbn
views.py
template_form = loansform();
in your view you can put intial data in form first get paramter from url then :
data = {'isbn': 154646486,}
form = Myform(initial=data)
in urls.py:
url(r'^checkout/(?P<isbn>\d+)/$',check_page)
view example :
def check_page(request, isbn):
data = {'isbn': isbn,}
form = Myform(initial=data)
template = 'mytem.html'
context = {'form': form,}
return render(request, template, context)
Say you've got url like
url(r'^checkout/(?P<isbn>\d+)/$')
In your view, when you instantiate form class, provide initial data to it like this.
form = YourFormClass(initial={'isbn': kwargs['isbn']})
kwargs contain url parameters, so you can get isbn from url.
I have a form with radio buttons and text fields. When I submit the form, the boolean field does not get created in the record. The boolean field is supposed to be updated via the radio buttons. What could be the issue here?
Here is the relevant part of my forms.py file:
CHOICES = (
(1,'yes'),
(0,'no')
)
class ServiceForm(forms.ModelForm):
one_time_service = forms.ChoiceField(required = True, choices = CHOICES, widget=forms.RadioSelect())
class Meta:
model = Service
fields = ('one_time_service')
This is my models.py one_time_service field
one_time_service = models.BooleanField(default=False)
This is my views.py:
def create(request):
if request.POST:
form= ServiceForm(request.POST)
if form.is_valid():
service_obj = form.save(commit=False)
service_obj.user_id = request.user.id
service_obj.save()
return render_to_response('services/service_created.html',
{'service': Service.objects.get(id=service_obj.id)})
else:
form = ServiceForm()
args= {}
args.update(csrf(request))
args['form'] = form
return render_to_response('services/create_service.html', args )
Edit: Here is my create_service.html
<form action="/services/create" method="post" enctype="multipart/form-data">{% csrf_token %}
<ul>
{{form.as_p}}
</ul>
<input type="submit" name="submit" value="Create Service">
</form>
I have no idea if this is the problem, but the line:
fields = ('one_time_service')
is wrong. That's not a single element tuple, that's a string with parens around it. Add a comma to make it a tuple:
fields = ('one_time_service',)
Edit: also, form.save() does not update any database records -- it creates a new one! That may be your problem.
I'm trying to loop through form fields and store them in the database. The problem is that it's always only the last field that gets stored. The previous ones are "skipped". Can I process the forms in Django in the following way?
models.py:
class Category(models.Model):
name = models.CharField(max_length=30, unique=True)
user = models.ForeignKey(User, blank=True, null=True)
class Meta:
verbose_name_plural = "Ingredience Categories"
def __unicode__(self):
return self.name
forms.py
class CategoryForm(ModelForm):
class Meta:
model = Category
fields = ('name',)
home.html template (I'm buildin my form "manually" because I want to be able to dynamically add more input fields via jQuery):
<h3>Insert New Categories</h3>
<form action="/" method="post" id="ingr-cat-form">{% csrf_token %}
<p><label for="id_0-name">Name:</label> <input type="text" maxlength="30" name="name" id="id_0-name"></p>
<p><label for="id_1-name">Name:</label> <input type="text" maxlength="30" name="name" id="id_1-name"></p>
<p><label for="id_2-name">Name:</label> <input type="text" maxlength="30" name="name" id="id_2-name"></p>
<input type="submit" name="ingrCatForm" value="Save" />
</form>
views.py:
def home(request):
if request.method == 'POST':
catform = CategoryForm(request.POST, instance=Category()) # store bounded form to catform
catformInstance = catform.save(commit = False) # create instance for further modification, don't commit yet
catformNames = request.POST.getlist('name') # get a list of input values whose element name is "name"
for name in catformNames: # loop through all name elements
catformInstance.name = name # modify form instance; insert current name
catformInstance.save() # save the instance to the database
return HttpResponseRedirect('')
else:
catform = CategoryForm(instance=Category())
context = {'catform': catform}
return render_to_response('home.html', context, context_instance=RequestContext(request))
Test Case Steps:
Insert the following values in the 3 input fields: value1, value2, value3
Press the submit button
Expected Result:
all 3 values are stored in the database
Actual Result:
only the last value (value3) is stored in the database
You create only one instance of catformInstance, then alter it's value each time in the loop. You are updating one row in the database instead of creating a new row each time.
Do this instead:
for name in request.POST.getlist('name'):
catform = CategoryForm({'name': name}, instance=Category())
catform.save()
Note that we pass in each name explicitly instead of the whole set of POST values; in that case it'll just grab the last name from the name list, then fail during the next iteration as name is no longer available from the request.