tags:

views:

133

answers:

0

Hi,

I'm using an inlineformset to present an object with all values read-only. can_delete is set to True and not read-only. The user should only be able to delete objects, but not change a value.

This is the code parts that I use:

view:

PMWPDRFormSet = inlineformset_factory(ProjectMembership, PMSWorkPlaceDayRate, form=ProjectMembershipWorkPlaceDayRateUpdateForm, max_num=10, extra=0, can_delete=True)

Form:

class ProjectMembershipWorkPlaceDayRateUpdateForm(forms.ModelForm):
    project_membership = forms.ModelChoiceField(ProjectMembership.objects, widget=HiddenInput())
    work_place = forms.ModelChoiceField(ProjectWorkPlace.objects)
    day_rate = forms.IntegerField(required=False)

class Meta:
    model = PMSWorkPlaceDayRate

Model:

class PMSWorkPlaceDayRate(models.Model):
    project_membership = models.ForeignKey(ProjectMembership)
    work_place = models.ForeignKey(ProjectWorkPlace)
    day_rate = models.PositiveIntegerField(max_length=11)

    created_by = models.ForeignKey(User, editable=False, related_name='project_membership_work_place_day_rate_creator')
    created = models.DateTimeField(auto_now_add=True, editable=False, verbose_name='creation date')
    modified_by = models.ForeignKey(User, editable=False, related_name='project_membership_work_place_day_rate_modifier')
    modified = models.DateTimeField(auto_now=True, editable=False)


    class Meta:
        unique_together = (("project_membership", "work_place"),)

Routine to make the form without the delete checkbox read-only:

for form in form_set.forms:
            for name, field in form.fields.items():
                if name != "DELETE":
                    field.widget.attrs['readonly'] = True
                    field.widget.attrs['disabled'] = True
    return form_set

Now I want to achieve in the view that if the user selected the delete checkbox that the object is deleted. I do it like this:

pmwpdr_form_set = PMWPDRFormSet(request.POST, request.FILES, instance=project_membership)
        if pmwpdr_form_set.is_valid():
            for form in pmwpdr_form_set.forms:
                try:
                    if form.cleaned_data:
                        if form.cleaned_data["DELETE"]:
                            pmwpdr_id = form.cleaned_data["id"]
                            pmwpdr =PMSWorkPlaceDayRate.objects.get(pk=pmwpdr_id.pk)
                            pmwpdr.delete()
                            #delete the corresponding ProjectMembershipWorkPlaceDayRate object
                            request.user.message_set.create(message='The Work Place Day Rate %s was deleted successfully".' % (pmwpdr_id))
                           (pmwpdr.project_membership.__str__()))
                except AttributeError:
                    pass
            if not pmwpdr_form_set.forms:
                request.user.message_set.create(message='You provided no data. Nothing has changed.')
            return HttpResponseRedirect(reverse('show_pmwpdr', args=(project_membership.id,)))

When I execute this code I get the following error:

MultiValueDictKeyError at /pm/projects/memberships/18/show_pmwdpr/
"Key 'pmsworkplacedayrate_set-0-id' not found in <QueryDict: {u'pmsworkplacedayrate_set-TOTAL_FORMS': [u'1'], u'pmsworkplacedayrate_set-INITIAL_FORMS': [u'1']}>"

The error is raised in the following line of code:

if request.method == 'POST':
        pmwpdr_form_set = PMWPDRFormSet(request.POST, request.FILES, instance=project_membership)

This is probably since the values are not transfered when an input field is disabled. But the interesting thing is that if I leave the day_rate field enabled it works. I would expect also an error for the still disabled work_place field.

That leads me to the assumption that something else is wrong and it might work the way that I tried it.

To bring this down to an answer: Why does my code not work and what would be a way to use inlineformset_factory with disabled fields and even so being able to delete an object!?