Django nested formsets - django

I have an edit object view that contains a formset(one or many if this matters), now I want to create a page that can display multiple edit object forms and submit it in a single form.
What is the correct way to achieve this task?

I found a solution.
I can enumerate my objects on edit page and use different prefixes for formsets based on these indexes. Here is an example:
First, you need enumeration, I achieved it using same input(checkbox) name with incremental values:
<input type="checkbox" name="counter" value="0">
...
<input type="checkbox" name="counter" value="1">
...
Counter numbers is the formset and other data serial numbers:
<!--Ordinary inputs-->
<input type="text" name="data0" value="value0">
<input type="text" name="data1" value="value1">
<!--Formsets-->
<input type="text" id="test0-0-data" name="test0-0-data" value="something">
<input type="text" id="test0-1-data" name="test0-1-data" value="something">
<input type="hidden" name="test0-TOTAL_FORMS" id="id_test0-TOTAL_FORMS" value="2">
<input type="hidden" name="test0-INITIAL_FORMS" id="id_test0-INITIAL_FORMS" value="0">
<input type="text" id="test1-0-data" name="test1-0-data" value="something">
<input type="hidden" name="test1-TOTAL_FORMS" id="id_test1-TOTAL_FORMS" value="1">
<input type="hidden" name="test1-INITIAL_FORMS" id="id_test1-INITIAL_FORMS" value="0">
Then if code you populate formsets like this:
counter = request.POST.getlist('counter')
for i in counter:
TestFormset = modelformset_factory(Test, form=TestForm)
test_formset = TestFormset(request.POST, prefix='test'+i, queryset=Test.objects.none())
I achieved HTML structure above with JavaScript.

Related

Django - Aggregate survey responses into string

I'm building out a survey in django. I would like to store the responses of the survey into a single string rather than a bunch of individual variables. My hope is that using this structure I can store surveys of varying lengths into a single table. I'm not sure how you loop through the survey responses and aggregate them and insert them into the db using django's ORM model. I'm guessing that you have to use raw SQL? Suggestions or URLs on where I might start appreciated. A more concrete example below.
Basic DB Design
PID=UUID
Responses=Char256
Survey example
<p>1. Item 1.<p>
<input type="radio" name="Q1" value="1">Very Inaccurate<br>
<input type="radio" name="Q1" value="2">Moderately Inaccurate<br>
<input type="radio" name="Q1" value="3">Neither Accurate or Inaccurate<br>
<input type="radio" name="Q1" value="4">Moderately Accurate<br>
<input type="radio" name="Q1" value="5">Very Accruate<br>
<p>2. Item 2.<p>
<input type="radio" name="Q2" value="1">Very Inaccurate<br>
<input type="radio" name="Q2" value="2">Moderately Inaccurate<br>
<input type="radio" name="Q2" value="3">Neither Accurate or Inaccurate<br>
<input type="radio" name="Q2" value="4">Moderately Accurate<br>
<input type="radio" name="Q2" value="5">Very Accruate<br>
<p>3. Item 3.<p>
<input type="radio" name="Q3" value="1">Very Inaccurate<br>
<input type="radio" name="Q3" value="2">Moderately Inaccurate<br>
<input type="radio" name="Q3" value="3">Neither Accurate or Inaccurate<br>
<input type="radio" name="Q3" value="4">Moderately Accurate<br>
<input type="radio" name="Q3" value="5">Very Accruate<br>
Assume the following responses
Q1: '1'
Q2: '2'
Q3: '3'
How do I insert this into my DB model as '123' rather than having a model that requires me to enter '1' into a variable q1, '2' into a variable q2, and '3' into a variable q3, etc.
Thanks!
To get you in the right direction. Either create a Question model with a name and a charfield of options. Your form would be created using a ModelForm. That way Django does most of the work for you.
An alternative is to use an external package. django-domande seems like a good survey app.

Use form information in external POST request

I've built a simple form to open up a JIRA ticket based on user input. I've almost got all of it, except I don't know how to use the form element in the POST request. Here's what I have so far:
<form target="_blank" action='http://baseurl.com/secure/CreateIssueDetails!init.jspa?pid=10517&issuetype=3&summary=Change+application+name+to+{{new_name}}&reporter={{request.user}}&priority=5&assignee=xxx' method='post'>
<label for="new_name">New name: </label>
<input id="new_name" type="text" name="new_name" value="{{item.name}}">
<input type="submit" value="Create JIRA ticket">
</form>
So I just need the value the user puts in the new_name element to be passed into the appropriate spot in the URL. How do I access that?
It sounds like you're getting POST and GET mixed. POST data would not be included in the URL itself, but rather in the request payload itself.
So, your URL would be http://baseurl.com/secure/CreateIssueDetails!init.jspa
The payload would be separately put in the body of the HTTP request.
If you need to use a GET method, the URL itself would be the same as above, but the URL that eventually gets hit would be http://baseurl.com/secure/CreateIssueDetails!init.jspa?new_name=WHATEVERVALUE.
If you need additional key-value pairs to get passed, just add them as hidden fields and pass them that way.
Your code, edited:
<form target="_blank" action='http://baseurl.com/secure/CreateIssueDetails!init.jspa' method='post'> <!-- ARE YOU SURE IT'S A POST REQUEST AND NOT A GET? -->
<label for="new_name">New name: </label>
<input id="new_name" type="text" name="new_name" value="{{item.name}}">
<input type="hidden" value="10517" name="pid">
<input type="hidden" value="3" name="issuetype">
<input type="hidden" value="5" name="priority">
<input type="hidden" value="Change application name to {{new_name}}" name="summary">
<input type="hidden" value="{{request.user}}" name="reporter">
<input type="hidden" value="xxx" name="assignee">
<input type="submit" value="Create JIRA ticket">
</form>
Makes sense?

Angular JS Form management

I am using Django, and would like to use Angular on my forms. Is there anyway to bind to form elements without having to explicitly write out each input element and add a ng-model?
I would like to be able to do this:
<form name="myForm" ng-submit="submitForm()">
<input type="text" name="username" />
<input type="text" name="password" />
</form>
And access the username/password in $scope as myForm.username and myForm.password, without having to do this:
<form name="myForm" ng-submit="submitForm()">
<input type="text" name="username" ng-model="myForm.username" />
<input type="text" name="password" ng-model="myForm.password" />
</form>
This would be useful when using Django's form builder, which automatically outputs forms based on the model they are based on, and saves having to write out and modify each form when changes are made.
I had to do this yesterday... I would do it like this:
forms.py
form_name = 'myForm' #or some other logic to get form class name
username = forms.CharField(widget=forms.TextInput(attrs={'ng-model': '%s.username' % form_name}))
or use https://github.com/jrief/django-angular
from django import forms
from djangular.forms.angular_model import NgModelFormMixin
class ContactForm(NgModelFormMixin, forms.Form):
subject = forms.CharField()
# more fields ...
This will output:
<input id="id_subject" type="text" name="subject" ng-model="subject" />

Accessing variables of a dynamic form

I am creating a form with cfloop and need to access each variable individually when submitting the form. I need to use the selected entries of the form in a loop that will add my selections to a database.
This is my form:
<form method="post">
<input type="hidden" name="isPost" value="1">
...
<cfoutput>
<cfloop query="client_admin_surveys">
<input type="text" size="35" name="surveyID" id="surveyID" value="#id#">
<input type="text" size="35" name="surveyName" id="surveyName" value="#name#">
<input type="checkbox" name="amplify" id="amplify">
<input type="checkbox" name="enchance" id="enchance">
<input type="checkbox" name="pacify" id="pacify">
<input type="checkbox" name="pacifyUrgent" id="pacifyUrgent">
</cfloop>
</cfoutput>
...
<input type="submit" name="submit" value="Submit">
</form>
After posting the form, the results group all of my selections because I have the same "name" for my form elements. I tried adding an i count next to each name to make it different but then I got a bit confused about how to process the fields.
You started down the correct path when you added the counter - go back and add that, something like:
<input type="checkbox" name="amplify#client_admin_surveys.currentRow#" id="amplify">
Would work.
I also sometimes like to add a form field for the 'counter' on the processing page
<input type="hidden" name="counter" value="#client_admin_surveys.recordCount#" />
Then on the processing page, you can loop over the counter and access the form fields using bracket notation
<cfloop from="1" to="#form.counter#" indexd="i">
<cfset thisAmplify = form["amplify" & i] />
<cfset thisEnhance = form["enhance" & i] />
<!---- more logic here --->
</cfloop>

How to make Chrome respect the names of my fields and not attempt to autocomplete

I have two different forms on my home page: one for logins and one for registrations. As you can see from the code, the forms have inputs with different names:
<h3> Log In </h3>
<form action="/login/" method="POST" class="form-vertical" style="padding-top: 5px">
<input id="id_login_username" type="text" name="login_username" maxlength="25" />
<input type="password" name="login_password" id="id_login_password" /><br>
<button type="submit" class="btn btn-info">Login</button>
</form>
<h3> Sign Up <small>(It's free!)</small></h3>
<form action="/register/" method="POST" class="form-vertical" style="padding-top: 5px">
<input id="id_register_username" type="text" name="register_username" maxlength="25" />
<input type="text" name="register_email" id="id_register_email" />
<input type="password" name="register_password" id="id_register_password" />
<input type="password" name="register_password2" id="id_register_password2" /><br>
<button type="submit" class="btn">Submit</button>
</form>
Which renders to this in Chrome:
What can be causing this? And how can I fix it?
That's a really good question and I'm sorry to say I have no idea. Did
you try to register once and also login at least once? If so, that
"might" be what's causing it as browsers come complete with the
"autoremember" feature.
Assuming autofill is enabled (it is by default), the reason it autofills the rest is because chrome's autofill server works on regular expressions, not exact matches.
All the regular expressions used for the various fields can be found in autofill_regex_constants.cc.utf8.
From there you can see that the expression for email field is "e.?mail" and for username it is "user.?name|user.?id|nickname|maiden name|title|prefix|suffix"
It appears a similar question has been asked before:
What is the correct way to stop form input boxes auto-completing?
There is an autocomplete attribute you can use in form fields.
<input id="id_login_username" type="text" name="login_username" maxlength="25" autocomplete="off" />