I have a Django application that allows people to create a record. A record can contain one or more people and the form by default contains three fields to capture a person's name. One for first name, one for middle initial and one for last name. When a person is creating a record they can add additional people by clicking a plus button. The plus button adds another set of three text boxes. They can do this for as many people as they want to add.
Once they click the plus button a minus button shows up next to each row so they can remove those fields if they decide to.
What is the best way to name the text fields so that I can get all the text fields and iterate through them in the back end of the application?
I thought if I named them all the same I would get an array of names when I do:
request.POST.getlist('firstname')
However, that is not the case. Instead I get the value from the last input field with that name.
Any suggestions are appreciated.
I suggest you take a look at formsets instead of reinventing this one.
https://docs.djangoproject.com/en/dev/topics/forms/formsets/
from django.forms.formsets import formset_factory
FormSet = formset_factory(MyForm, extra=2)
formset = FormSet()
print formset.forms # you will see it is a collection of MyForm objects
You can dynamically add / remove formsets by modifying a the "management form" and adding the next form (you can copy {{ formset.empty_form }} and modify the IDs to be the N-th form) and there are many examples online of how to do so:
How would you make a dynamic formset in Django?
Dynamically adding a form to a Django formset with Ajax
Related
I've spent a fair amount of time the last day or so exploring the can order field with Django Formsets but I can't for the life of me actually figure out what it's for. Apparently it doesn't update the database...and it does put an order number field with the form....but beyond that what is it for?
I can't find any useful documentation on how to actually use this field. Do I have to write Javascript in order to get this field to do anything actually meaningful?
I get the delete option...and you have to add code in to delete the record...So I guess I'm to take it the same is required for the can_order field?
Sorry if this is a silly question but I've spent more time trying to figure this out than what would be reasonable by now.
All it does is add an integer ORDER field to each form in the formset so you can manually order them after instantiating the formset. Just imagine your forms have a title with this imaginary formset data. You can use ordered_forms to iterate through each form, inspect its cleaned_data, and change it's ordering before returning the form in your context.
formset = ArticleFormSet(data)
if formset.is_valid():
for form in formset.ordered_forms:
if form.cleaned_data['title'] = 'My form title'
form.cleaned_data['ORDER'] = 2
form.save()
The can_order adds a field to the formset, just like the can_delete does. You do not NEED JavaScript, but you can use it, for example if you use JavaScript to drag and drop the forms in the formset. You can sort them and then you can change the name attribute to reflect the new order by accessing the specific form by using it's id in your JavaScript.
The can_order IS like the can_delete, in that the can_order` will simply add the following to each of the forms in your formset, where N = 0, 1, 2, 3, 4...
<input type="number" name="form-N-ORDER" id="id_form-N-ORDER">
What can you do with this without JavaScript? Add an order field to your model, and then you can get the forms order in your post, and set the order field of your model to equal that.
I am using Django inline formset with option to add additional forms at runtime. Some of the fields display the default values as already defined in the related models. However, when new rows of formsets are added, most of the fields are "blank" (i.e. the default values do not show up in those fields), except the date field which show the date widget.
As in the image above, a new row containing the blank (red rectangle) field fails to show the default value (as otherwise available in the rows available at page load).
I am currently using jQuery to fill the blank fields capturing the "rowadded" function but find it quite a mess, as managing the code is cumbersome.
Is there a ready to use function/plugin available in Django which can be used to fill the fields on addition of new row/s (at runtime)?
When you render the form, i.e. form = MyForm(), specify the instance of the form like so:
form = MyForm(instance=Model.objects.get(pk=1).
This will populate your form with the object from Model with a primary key of 1.
I'm new to Django and struggling to find the best/correct way to populate a dropdown list in a ModelChoiceField within a form using a list I have stored in a database.
The basic code below works fine with my view passing the form as context to my template but the drop-down returns a 'dictionary' like list with the ugliness or the brackets, colons and the key name (see the attachment)
from django import forms
from .models import constituency
class ConstituencyForm(forms.Form):
ConstituencySelection = forms.ModelChoiceField(queryset=constituency.objects.all().values('name'))
My questions are:
1/ The purpose of this page will be to select one of 650 areas from the dropdown list and have it highlighted on the map. Is this an appropriate way to approach the task (using a queryset within the form itself)?
2/ How do I clean up this list, it should simply read:-
Aldershot
Aldridge-Brownhills
Altrincham and Sale West
and so on and so on
Your help would be forever appreciated!
Thanks,
Phil #anoobinneed
Using values_list() with flat=True will do it.
Change:
queryset=constituency.objects.all().values('name')
To:
queryset=constituency.objects.all().values_list('name', flat=True)
I'm working with Django 1.4 FormWizard (specifically, NamedUrlFormWizard)
first, the basics. i have a 3 step form wizard i'm building. The final outcome is along the lines of defining a template, and then choosing some people to use it, and then send them an email.
Step 1 - enter in basic template data (name, description, etc)
Step 2 - define a list of N fields, each with their own set of attributes but all identical in structure
Step 3 - choose one or more users to email, AND customize the contents of this email before saving
so far, in the form wizard:
Step 1 is a standard Form class, and works just fine.
Step 2 is a standard Formset class, and works just fine.
Step 3 is giving me some trouble. It needs to be a formset (list of email addresses), but also an additional form input field with email text. I can't figure out how to have both a formset in addition to a non-repeating form input on the same page inside of a form wizard.
in a perfect world, i could define a Formset as just another form field in a Form definition.
ie:
class EmailAddressForm(forms.Form):
email = forms.EmailField()
class EmailAddressesAndText(forms.Form):
emailText = forms.Textarea()
emailAddressFormSet = formset_factory(EmailAddressForm, etc etc)
then point my FormWizard page at 'EmailAddressesAndText' and be done with it. but its not a perfect world. Any ideas on how I can achieve such a thing?
You can use get_form() method of WizardView to customize the form for particular step. Refer: WizardView.get_form. This answer can help you to add a field
Another option would be to add the field in formset and through JS disable and hide all instances other than first one.
I have a many to many link between Foos and Bars. I don't particularly like the multi select widget so was thinking of having a widget which allows selecting a single Bar and a button to add more choice fields.
From what I've been reading formsets may be the answer. Is it valid to have a formset made up of a form with only one choice field or is there a better way to get the behaviour I'm looking for?
I wouldn't worry about the quantity of fields in the form. If your 'child' model only has the one field, then I'd say it's perfectly valid to use an formset with single field forms in this application.
You should take a look at inline formsets, they should help with exactly what you need. Although I'm not 100% sure they work for M2M...
additional thought: If it doesn't inline forsmet doesn't work directly with M2M, you can just use a model formset, and manually save the relationship in your view after using formset.save(commit=False). docs: formset saving