Your code is not only a lot more complicated than it has to be, it also has some very significant security holes. By the fields in it, I take it FamilyMember
is your custom user model.
Let's say I'm a regular family member who can edit my family. I get a form that has a lot of hidden inputs, including is_staff
and is_superuser
. Any nitwit with a webpage debug toolbar can change the value of these hidden input fields to True
. Now I change the value of these fields to True
, send in the form, and tada: I'm a superuser who can fuck up your complete site.
A HiddenInput
widget is not a replacement for actual server-side validation and security. The only valid use-case for a hidden input field, is a default value that a user generally shouldn't change in that specific form, but that doesn't pose any security treats when it is changed, either because the user is in some way allowed to change it, or because the server overrides the change or denies the request.
What you need to do is use a custom form in your formset, that only includes the fields you want to include. For your FamilyMember
model, it can be the following ModelForm
:
class FamilyMemberForm(forms.ModelForm):
first_name = forms.CharField(max_length=50, required=True,
widget=forms.TextInput(attrs={'class': 'input-small'}),
error_messages={'required': 'Please enter a first name'})
...
class Meta:
model = FamilyMember
fields = ['first_name', 'middle_name', 'last_name', 'state', 'zip_code']
widgets = {
'middle_name': forms.TextInput(attrs={'class': 'input-mini'}),
...
}
This will ensure that a user can only edit the fields they're supposed to edit (the ones you explicitly added to the form), and will make your formset class a whole lot less complicated. You can pass the form to use to your formset factory using the form
argument:
family_member_formset = FamilyMemberInlineFormSet(request.POST, request.FILES,
queryset=FamilyMember.objects.filter(family=request.user.family.id), prefix='fm',
form=FamilyMemberForm)
As for you second question, I'm not entirely sure what you want. By current family member, do you mean the logged in user? If that's the case, this will suffice:
if request.user.is_staff:
email_list_description = <queryset for staff members>
else:
email_list_description = <queryset for non-staff members>
If that's not what you meant, where exactly are you using this email_list_description
and on what user's privileges should it be based?