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)
Related
I have select field in my html
<select class="form-select" name="is_recurrent" id="payment">
<option value="False" class="option" selected>One-time fee</option>
<option value="True" class="option">Subscription</option>
</select>
I have model Donate in models.py
class Donate(BaseModel):
is_recurrent = models.BooleanField(default=False)
...
I have form in forms.py
class DonateForm(forms.Form):
is_recurrent = fields.BooleanField(???)
...
How can I pass True into form if subscription is selected and false if one-time fee is selected
When you instantiate your form in the view, you pass in the POST data:
form = DonateForm(data=request.POST)
That will auto-populate the form with the information that the user selected in the form prior to form submission.
If you're using Django-forms, it's really easy to do so, you don't even need to build the form! From your HTML code I can see you are trying to do so, creating an HTML form, I recommend you going through Django-forms information page (https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Forms) since you don't really need to create all of the input boxes, the Django Forms takes care of that for you, you just need to pass the variables you want to edit using the form.
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 :)
I have a app where users can register their company and then select a number of settings from a list. Both the company and services are different models.
class Company(models.Model):
name = models.CharField(max_length=100)
(...)
class Service(models.Model):
name = models.CharField(max_length=100)
linked_companies = ManyToManyField(Company, blank=True)
What I want is to have a large list of services, with checkboxes behind their names, so the owner can quickly select the services that he wants to connect to his model. This used to be done through the admin interface, but due popular demand this feature is moved to 'the front'.
The problem is that I do not know how to fit this into the traditional (generic) view/form combinations that we' ve been using so far, since two different models are involved.
I am trying a more custom solution, but have hit a wall and I am wondering if you could help me. I have created a html page that should display both the list of services and a 'save' button.
<form action="." method="POST" class="post-form">{% csrf_token %}
<ul>
{% recursetree services %}
<li>
<label><input type="checkbox" name='service' value={{ node.pk }}><h3>{{ node.name }}</h3></label>
{% if not node.is_leaf_node %}
<ul class="children">
{{ children }}
</ul>
{% endif %}
</li>
{% endrecursetree %}
</ul>
<button type="submit" class="save btn btn-default">Add Selected
</button>
</form>
I am using the following ModelForm:
class FacetForm(forms.ModelForm):
class Meta:
model = Services
fields = ['linked_tenants', 'name']
widgets = {
'linked_tenants' : CheckboxSelectMultiple()
}
This HTML page seems to work as intended, showing a long list of services with checkboxes after their names.
However, I have trouble creating a function view. Together with a collegue the following view was created
class FacetList(TenantRootedMixin, TemplateView):
def get_context_data(self, **kwargs):
d = super(ServiceList, self).get_context_data(**kwargs)
d['services'] = Services.objects.all()
d['current_company'] = self.context.company.id
return d
def form_valid(self, *args, **kwargs):
return super(ServiceList, self).form_valid(*args, **kwargs)
This view works in the sense that it shows all of the relevant information (with the checkboxes). If I change the query to filter the services by 'company id'. the view works as desired as well.
The problems I have revolve around the fact that pressing 'save'. crashes the program, throwing the following error.
'super' object has no attribute 'post'
Our program works mostly through generic classbased views and modelforms, so we have relativly limited experience with creating our own custom solutions. By my own estimation the problem seems to be twofold:
The view is probably not configured right to process the 'post' data
It is questionable if the data will be processed to the database afterwards.
Though are 'sollution' is currently flawed, are we looking in the right direction? Are we on the right way to solve our problem?
Regards
I believe you are on the right track. What I would suggest is to not be afraid to move away from generic views and move toward a more custom solution (even if you are inexperienced with it.)
The first routine that comes to my mind would be as follows:
gather all the id's that were checked by the user into a list from request.POST
Update the appropriate object's M2M field to contain these new id's.
Save the fore-mentioned object.
[Edit]
One thing I have trouble with is gathering the ID' s from the request.POST. Could you provide me with an example on how to do this?
Sure, from your HTML file I see you are creating inputs with name=service. That leads me to believe you could do something like:
ids = request.POST.get('service')
but to teach you how to fish rather than giving you a fish, you should try to simply:
print request.POST.items()
This will return and print to the console everything that was posted from your form to your view function. Use this to find out if you are getting a list of id's from the template to the server. If not, you may have to re-evaluate how you are building your form in your template.
Your first point is correct: TemplateView has no "post" method defined and that is why you get the error message when you call super().form_valid. You must either define it yourself or use a CBV which has a post method that you can override (e.g. UpdateView)
And I also believe that your second point is correct.
You would need to use an UpdateView to use the built in functionality (or CreateView).
I had a similar problem to solve (selecting values from many-to-many fields in the front-end) and I ended up with doing it "by hand" because I could not get it to work with CBV. "by-hand" => parse the values from the form, update the database, return HttpResponse
You might want to look at ModelFormSets:
https://docs.djangoproject.com/en/1.11/topics/forms/modelforms/#model-formsets
Hope this helps!
Alex
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.
I am not quite sure about if i am taking the right approach to accomplish this. What i want is to (change the css for) / (use some jQuery methods on) the form elements rendered by the modelformset that have pre-filled data. For example i have the following modelformset.
EduFormSet = modelformset_factory(models.CandidateDegree,
form=forms.CandidateDegreeForm)
edu_formset = EduFormSet(prefix='candidate_degree',
queryset=models.CandidateDegree.objects\
.filter(candidate=can))
when i pass this formset to the template it renders forms for all the existing CandidateDegree objects with the pre-filled data and a blank form as well.
What i am trying to achieve is not to show the pre-filled forms but just the data for the objects that are already created and append an edit button to the element (using jQuery) which would then show the form. And at the end of the object list show the blank form generated by formset.
i am aware that i could pass all the CandidateDegree objects related to a Candidate as a seperate dictionary to show the information. but in that case how do i append the form to the formset so that the dynamically generated forms become the part of the formset and all the information is saved when a user clicks on a submit button.
what would be the best approach to achieve something like this ?
You don't have to show the complete form, you can loop over the formset like this:
{% for form in edu_formset %}
form.FIELDNAME#1.value
form.FIELDNAME#2.value
etc.
{% endfor %}
<!-- Manually render empty form for new entry -->
<div class='input'>
<label>Locality: </label> <input id="FIELDNAME#1" disabled=disabled value="">
<label>Country: </label> <input id="FIELDNAME#2" disabled=disabled value="">
etc.
</div>
So you're only showing the database values of all objects send to the template, not the form inputs.
Then indeed with minimal jquery (or plain javascript) you can show/hide the div.input