Reputation: 25554
I'm out of clues on how to customize a form with checkboxes. Basically I need to choose in the queryset only two choices of a list, I've tried to use "filter(pk=2, pk=3)" but it is not working. I've also to make the "pk=2" choice checked and not editable and the "pk=3" editable and not checked by default.
My form(does not work, filter(pk=2, pk=3) is not valid):
class PrimaryCategoryForm(forms.ModelForm):
primarycategorytype = forms.ModelMultipleChoiceField(queryset=PrimaryAdCategoryType.objects.filter(pk=2, pk=3), required=True, widget=forms.CheckboxSelectMultiple)
Any clues on how to achieve this?
Best Regards,
Upvotes: 2
Views: 1911
Reputation: 13308
Trying building your queryset using the pythons union operator -
class PrimaryCategoryForm(forms.ModelForm):
set_1 = PrimaryAdCategoryType.objects.filter(pk=2)
set_2 = PrimaryAdCategoryType.objects.filter(pk=3)
qs = set_1 | set_2
primarycategorytype = forms.ModelMultipleChoiceField(queryset=qs,
required=True,
widget=forms.CheckboxSelectMultiple)
The |
operator is creating a new set with all items from set_1
and all items from set_2
.
UPDATE
Whilst the method above will support creating complicated sets. Martin's suggestion in the comments is probably sufficient if you simply want to pick a few pk's -
class PrimaryCategoryForm(forms.ModelForm):
qs=PrimaryAdCategoryType.objects.filter(pk__in=[2,3])
primarycategorytype = forms.ModelMultipleChoiceField(queryset=qs,
required=True,
widget=forms.CheckboxSelectMultiple)
EDITABLE CHECKBOXES
I think when it comes to making the checkboxes editable and preselected you may need to resort to javascript. Perhaps add data-attributes to the widget, then create a jquery function that manipulates the checkboxes on the basis of the data-attributes. Something like -
attrs = {'data-selected-value': 2, 'data-readonly-value': 2}
primarycateogrytype = forms.ModelMultipleChoiceField(attrs=attrs)
Then in the javascript -
var readonlyCheckboxValue = $('#your_mulliplecheckboxselect).data('selected-value');
var $readonlyCheckbox = $('#your_multiplecheckboxselect .input[value=readonlyCheckboxValue]');
$readonlyCheckbox.attr('readonly', true);
I haven't tested this code, but it should give you an idea of what I'm suggesting. Do check out the data-attribute if you haven't come across it already - it's pretty awesome.
Upvotes: 2
Reputation: 1571
Its possible that you would need the form to be dynamic in nature. You would need to override the __init__
method for the class.
Something like this here: How to Modify Choices of ModelMultipleChoiceField
An example:
class ServiceStartForm(forms.Form):
serviceList = service.models.Service.objects.all()
print serviceList.count()
b = {}
for aService in serviceList:
b[aService.id] = aService.name
c = b.items()
print "Within the form, ", serviceList.count()
serviceChoice = forms.ChoiceField(choices=c, widget=forms.Select())
input_directory = forms.CharField(max_length=200)
output_directory = forms.CharField(max_length=200)
def __init__(self, *args, **kwargs):
super(ServiceStartForm, self).__init__(*args, **kwargs)
serviceList = service.models.Service.objects.all()
b = {}
for aService in serviceList:
b[aService.id] = aService.name
c = b.items()
self.fields["serviceChoice"].choices = c
Upvotes: 1