Django WebTest: Check/uncheck checkbox by value - django

I've got a form with a set of checkboxes (all under the same field name) in my WebTest response, and I'd like to uncheck some of them according to their value. I've tried this:
my_form = response.forms['form-i-want']
for i in range(len(my_form.fields.get('field-i-want'))):
if my_form.fields.get('field-i-want')[i].value == "value-to-uncheck":
my_form.fields.get('field-i-want')[i].checked = False
Obviously this is very hacky looking code and there must be a better way. Also, this doesn't actually uncheck the box I want: when I then iterate through the checkboxes in the form there is no longer an element with the value value-i-want: the value has been set to None. And when I submit the form it behaves as if the nothing was done to the form.

Unfortunately your method for setting the checked status of the input will indeed have the unwanted side-effect of the input element being deleted.
As per the docs, to mark a checkbox input as being checked you will want to write:
my_form['field-i-want'] = True
Where 'field-i-want' is the value of the name attribute of the input element.

Related

how to match a field name with another field name

I have two fields that run throughout a website that I would like to match so that when a user inputs a value either of the fields, it will match the other field. I'm using Sitecore Rocks and am trying to use a query to do this.
select ##h1#, ##Title#
from /sitecore/Content/Home//*[##h1# !="##Title#"];
update set ##h1# = ##Title# from /sitecore/Content/Home//*[##Title# = "<id>"];
What am I missing here?
This article talks about tapping in to the item:saving event which allows you to compare the fields values of the item before and after the changes:
http://www.sitecore.net/Community/Technical-Blogs/John-West-Sitecore-Blog/Posts/2010/11/Intercepting-Item-Updates-with-Sitecore.aspx
Using this, you can determine which field has been amended, then change the other to match.
I've had to do something similar to this when a new field was added, and we wanted to set the initial value equal to an existing field. It may be a bug in Sitecore Rocks, but I found it would only update a field when a static value was part of the query.
When I ran ##h1# = ##Title#, the query analyzer would return the correct number of items updated, but no values were actually updated. However, ##h1# = '<id>' worked perfectly. After trying a number of things, I found this did what I wanted.
update set ##h1# = '' + ##Title# from /sitecore/Content/Home//*[##Title# = "<id>"];
I hope that helps.

Django check if any field is blank?

I there any way to check if any field Null or Empty without checking each and every field. i have seen this Django check to see if field is blank?. But in this case we have to check each and every field.
if i am wrong please correct me. Thanks for the help!
There's no way around checking all the fields, but you could write some helpers.
any_blank_fields = all((field.blank for field in Model._meta.fields))
Oh, you're talking about Falsy values, not blank=True. In that case, you really have no choice but to do some loops, or a list comprehension.
instance = Model.objects.latest('pk')
all_fields_filled = all((getattr(instance, field.name) for field in
instance._meta.fields))

Django skip inline field

I have an inline where the first field is always selected by default. Since both are required, is it possible to only validate and insert/update when the second field is also selected or I need to also define a default value for the second field? (Otherwise I will always get errors on the rows where only the first field is set...)
Update
I'm overriding the first widget (TextInput) render. If I set to empty then it works but I want this field to behave almost like a label.
def render(self, name, value, attrs=None):
if name == "opinion_set-0-topic":
value = "first thing"
if name == "opinion_set-1-topic":
value = "second thing"
if name == "opinion_set-2-topic":
value = "third thing"
Update 2
I need something like, if field 2 isn't set (gives "This field is required.") then bypass the form error and simply ignore the rows where this happens...
The situation is:
you have a main form to save
you have an inline subform with mandatory fields, some with default values and some without default values
Then, if you don't set all mandatory values in the inline, you get "This field is required" error.
One way to skip this situation is defining "extra = 0" in the admin.py definition of the inline form.
This way you are not forced to insert an inline object along the main one, but you can do it if you want, just clicking "+ Add another <inline>".

Django formset - show extra fields only when no initial data set?

I have a page that displays multiple Formsets, each of which has a prefix. The formsets are created using formset_factory the default options, including extra=1. Rows can be added or deleted with JavaScript.
If the user is adding new data, one blank row shows up. Perfect.
If the user has added data but form validation failed, in which case the formset is populated with POST data using MyFormset(data, prefix='o1-formsetname') etc., only the data that they have entered shows up. Again, perfect. (the o1 etc. are dynamically generated, each o corresponds to an "option", and each "option" may have multiple formsets).
However if the user is editing existing data, in which case the view populates the formset using MyFormset(initial=somedata, prefix='o1-formsetname') where somedata is a list of dicts of data that came from a model in the database, an extra blank row is inserted after this data. I don't want a blank row to appear unless the user explicitly adds one using the JavaScript.
Is there any simple way to prevent the formset from showing an extra row if the initial data is set? The reason I'm using initial in the third example is that if I just passed the data in using MyFormset(somedata, prefix='o1-formsetname') I'd have to do an extra step of reformatting all the data into a POSTdata style dict including prefixes for each field, for example o1-formsetname-1-price: x etc., as well as calculating the management form data, which adds a whole load of complication.
One solution could be to intercept the formset before it's sent to the template and manually remove the row, but the extra_forms attribute doesn't seem to be writeable and setting extra to 0 doesn't make any difference. I could also have the JavaScript detect this case and remove the row. However I can't help but think I'm missing something obvious since the behaviour I want is what would seem to be sensible expected behaviour to me.
Thanks.
Use the max_num keyword argument to formset_factory:
MyFormset = formset_factory([...], extra=1, max_num=1)
For more details, check out limiting the maximum number of forms.
One hitch: presumably you want to be able to process more than one blank form. This isn't too hard; just make sure that you don't use the max_num keyword argument in the POST processing side.
I've come up with a solution that works with Django 1.1. I created a subclass of BaseFormSet that overrides the total_form_count method such that, if initial forms exist, the total does not include extra forms. Bit of a hack perhaps, and maybe there's a better solution that I couldn't find, but it works.
class SensibleFormset(BaseFormSet):
def total_form_count(self):
"""Returns the total number of forms in this FormSet."""
if self.data or self.files:
return self.management_form.cleaned_data[TOTAL_FORM_COUNT]
else:
if self.initial_form_count() > 0:
total_forms = self.initial_form_count()
else:
total_forms = self.initial_form_count() + self.extra
if total_forms > self.max_num > 0:
total_forms = self.max_num
return total_forms

Processing dynamic MultipleChoiceField in django

All the answers I've seen to this so far have confused me.
I've made a form that gets built dynamically depending on a parameter passed in, and questions stored in the database. This all works fine (note: it's not a ModelForm, just a Form).
Now I'm trying to save the user's responses. How can I iterate over their submitted data so I can save it?
The MultipleChoiceFields are confusing me especially. I'm defining them as:
self.fields['question_' + str(question.id)] = forms.MultipleChoiceField(
label=mark_safe(required_tag +
question.label + "<br/>Choose any of the following answers"),
help_text=question.description,
required=question.required,
choices=choices,
widget=widgets.CheckboxSelectMultiple())
When I select several options, the actual posted data is something like:
question_1=5&question_1=6
Will django automatically realise that these are both options on the same form and let me access an iterable somewhere? I was going to do something like:
for field in self.cleaned_data:
print field # save the user's response somehow
but this doesn't work since this will only return question_1 once, even though there were two submitted values.
Answer: The for loop now works as expected if I loop through self.fields instead of self.cleaned_data:
for field in self.fields:
print self.cleaned_data[field]
... this doesn't work ...
Are you sure? Have you tested it? Normally the cleaned_data value for a MultipleChoiceField is a list of the values chosen on the form.
So yes, it only returns question_1 once, but that returned value itself contains multiple values.