I have following question : I would like to have a page on which I want to use Select2 , but list of selection options should come from my database.
I have a table from which I would like to select entries using something like this:
SELECT DISTINCT field FROM table ORDER BY field ASC
This will give a list I want to use in select. In PHP it was quite simple to use it, but in Django (which I learn) I am not sure how it can be achieved.
For some reasons I do not want to use models and ORM, but would like to use direct selects to DB tables which I define by myself in view.
To make this example simple, lets take it from this page :
Django: Select option in template
Lets assume I have DB table organizations which has two field: ID , Name
I want to select 'name' using the select listed above. After I fetch those data I want them to be used in
<select>
<option>org1</option>
<option>org2</option>
.....
</select>
In your views you have to send organizations data using some query set.
For example in your view you can return:
return render(request, template_name, {'organisations': Organisation.objects.all()})
The above queryset can be replaced by any other query set.
Now in template file you can loop through your organisation data like:
<select name="somename">
{% for organisation in organisations %}
<option value="{{ orgnisation.id }}"> {{ organisation.name }} </option>
{% endfor %}
</select>
The name field in select tag can be used to get the fields when you unpack the post data in your views.
Related
I am using a model form that has 3 fields - name, country and city. My template looks like this-
<form method="post" id="personForm" data-cities-url="{% url 'ajax_load_cities' %}">
{% csrf_token %}
{{form}}
<input type="submit" value="Submit">
</form>
Following this is a bit more jQuery code that fetches the id for the "country" field using a code like this -
$("#id_country").change(function ()....
Two things I need to mention here, no where in my code I have id_country except from this jQuery code. Also I haven't set the id attribute for the country field anywhere.
So my question is , is this a thing in django or in jQuery where you can get the id for a field using id_ in front of the field name?
I read the django documentation, haven't seen anything like this.
What am I missing here?
Thanks for any input.
When one renders a Django form, it automatically renders an id attribute on the form fields. As you noticed this id is of the form id_<field-name>. This is noted in the documentation in the section Working with form templates:
Note that each form field has an ID attribute set to id_<field-name>
Hence you have an id as id_country because you have a form field named country. If you were to have a field named foo its id would be id_foo.
In a django template, I need to use forloop.counter0 to access an element in a list. For instance:
{% for foo in bar %}
<p>{{data[{{forloop.counter0}}]}}</p>
{%endfor%}
That notation doesn't work - I guet "cannot parse the remainder: [{{forloop.....]"
So... how do I use the variable forloop.counter0 as an index for another variable (data) which is a list in a django template?
EDIT: why I think i need to do that.... Short story is that I have an inlineformset. The formset (let's call it "Discounts") is simple - a description (just a label to show users) and a % discount associated. The user only needs to enter the %. That formset is used within a Customer form. Using inlineformset_factory(Customer, Discounts, ....). There are also 2 foreign keys that must be set in that discount form (to the Customer instance being created, and to the MetaGroup, see below). But those are hidden fields and it's easy to do.
However, the number of forms I need in that formset is determined by the instances in another table (let's call it "MetaGroup"). E.g. metagroupe contains entries for stuff like say Chairs, Tables, Sofa. My "Discounts" inlineformset provides users a way to set the discount % on each of those MetaGroup.
Thus in the template I do:
...
<tbody>
<managmeent forms, error stuff here>
{% for form in formset %}
<td>{{form.field.pourcent}}</td>
That's the forloop in which I need to access the data[fooloop.counter0]. data is provided by the inclusion I use to render that table/snippet.....
EDIT: the accepted answer is solution to the narrow question - which is that I probably shouldn't do that. For the wider issue (e.g. as to why I thought I needed to do this), I ended up using what is detailed here.
Please don't. Django templates are deliberately restricted, not to do this since business logic belongs in the view, not the template.
In the view, you can zip bar and data, so then the view looks like:
def my_view(request):
bar = …
data = …
context = {
'bar_data': zip(bar, data)
}
return render(request, 'some-template.html', context)
and render this with:
{% for foo, datum in bar_data %}
<p>{{ datum }}</p>
{%endfor%}
I have an option list in html.
<select>
<option value="Please select" disabled selected>- Please Select -</option>
<option value="Iphone">Iphone</option>
<option value="Samsung">Samsung</option>
</select>
When the user select one of the option, the particular table with data will appear.
In views.py:
dev_model = Device.objects.filter(name='name').all()
I want to get the data from html, then filter the option with my database in field 'name'.
If they are same, the data will be retrieved and display in html.
You may want to use a Django Form to accomplish this.
In a file called forms.py (in the same directory as your models.py) you will have something like:
from django import forms
class MyForm(forms.Form):
NAME_CHOICES = (('Iphone', 'Iphone'),
'Samsung', 'Samsung'))
name = forms.ChoiceField(choices=NAME_CHOICES)
Then, in your view, pass the form through context and render it in your django template. I would suggest ModelForm instead of Form a lot of the time, but I don't have any specifics about your application/use case.
When the form is POSTed back to your view, you should be able to get the data by using
form=MyForm(request.POST)
if form.is_valid():
name = form['name'].value()
The link to the documentation should be a good point to get you started
To display the data as soon as the user selects the correct field, you can do this with one of two approaches:
Use ajax if you want the filtering to happen on the server side
Use DataTables to pass all the data to the browser and have the user filter their display at their convenience.
You question is too broad to provide a specific answer while lacking the necessary details behind your attempt I have provided a starting point for your forms and links to the necessary documentation. I hope this helps
You can keep mapping of device to a particular value like this:-
DEVICE_TO_MAPPING = {
0:'Samsung',
1:'Iphone',
}
And then use this mapping to send in context as variable like "devicemapping" to render in html in template, you can do it like.
<form name="device-form" method='POST' action='.'>
<select>
<option value="{{device_value}}" disabled selected>- Please Select -</option>
{% for device_value, device_name in devicemapping.items %}
<option name='{{device_value' value="{{device_value}}">{{ device_name }}</option>
{% endfor %}
</select>
</form>
In your views.py you can filter the data using Mapping.
device_value = request.POST.get('device_value')
device_name = DEVICE_TO_MAPPING.get(device_value)
dev_model = Device.objects.filter(name=device_name)
I'm trying to duplicate the functionality of this manually created <select> using a proper Django form.
{% regroup roll_counts by get_type_display as roll_list %}
<select name="film">
<option>Select a film</option>
{% for type in roll_list %}
<optgroup label="{{ type.grouper }}">
{% for film in type.list %}
<option value="{{film.id}}">{{ film.manufacturer }} {{ film.name }} ({{ film.count }})</option>
{% endfor %}
</optgroup>
{% endfor %}
</select>
The queryset for roll_counts looks like this:
roll_counts = Film.objects\
.filter(roll__owner=owner, roll__status='storage')\
.filter(format=camera.format)\
.annotate(count=Count('name'))\
.order_by('type')
I'm trying to recreate this using some sort of Django ModelForm to be able to actually validate data submitted to the form. The ultimate goal is to be able to "load" a camera with a roll of film. Which is to say: associate a Roll (with a foreign key to Film) with a particular Camera and mark said camera with a status of loaded. So the <select> displays data that isn't being updated by the form. What needs to be modified are the Roll and Camera models, not the Film model. But I assumed all that could be handled within the view that receives data from the form.
I'm unsure how to get a ModelForm to display the aforementioned roll_count query (and nested/optgroup <select>) since it doesn't relate to a single field on that Film model.
Any ideas on how to proceed?
Update:
The accepted answer got the nesting part of the puzzle solved, but another part of it was getting the data passed from the view into the form and the QuerySet for the field working.
In the view, you can pass whatever you want to a form instance:
form = LoadCameraForm(owner=owner, format=camera.format)
In the form, I added a custom __init__ (note the owner, format between *args and **kwargs):
def __init__(self, *args, owner, format, **kwargs):
super().__init__(*args, **kwargs)
self.fields['roll_counts'].queryset = Film.objects\
.filter(roll__owner=owner, roll__status='storage')\
.filter(format=format)\
.annotate(count=Count('name'))\
.order_by('type')
(I'm still unsure how to get my annotated count to show up yet.)
Then to put all the pieces together, the field entry in the form looks like this:
roll_counts = GroupedModelChoiceField(\
label='Pick a film to load',\
queryset=None,\
group_by_field='type')
I did that once! See my snippet here :) https://djangosnippets.org/snippets/10573/
There is no built-in form field that can do what you want, so you will have to create your own custom field and a widget for rendering the field to HTML. Take a look at django.forms.fields module and you will see how the form fields are defined. Though for some, it may be a challenge to get it right.
To be honest, i would recommend to search for another option for displaying your form. You could have a select field for type and when selected, you can load the options for film using ajax?
Just my 2 cents :)
How do I control by what my list gets regrouped from the view? I have a page with a drop down for attributes the list can be grouped by. Once an attribute selected it goes into the view and it will generate the list - I want the template to pick up the regroup attribute somehow.
{% regroup cities by country as country_list %}
this works, however when I pass the 'country' as a string from the view, it doesn't:
view:
return render_to_response('parts/action_items.html',
{
'action_item_list': action_items,
'view_filter': 'country'
}, template.RequestContext(request))
template:
{% regroup cities by view_filter as country_list %}
What do I pass into it to make it work?
It isn't possible to use a variable when using the template tag, because the regroup attribute is treated as a string.
You could regroup the list in the view instead. Importing the regroup tag in your view might work. If that doesn't, you can implement the functionality yourself. See this question for more info.
I used this django snippet for dynamic_regroup in my custom templatetags and was able to pass in the view_filter to regroup that way (replacing {% regroup ... %} with {% dynamic_regroup ... %}