I want to be able to do:
def update_profile(request, username):
user = Profile.objects.get(user__username=username)
# update subset of profile, eg value_to_company is set in request.POST
# but user (or an arbitrary number of other attributes) is not
profile = ProfileForm(request.POST, instance=user)
if not profile.is_valid():
print profile.errors #user is required
The problem that I have with this is that user definitely exists and is part of the instance, and I can’t find anything in the docs to suggest that instance data wouldn’t get into the bound data. But I also can’t find anything that explicitly says that it will.
(The rest of this is justification for why I’m doing things the way I am, and ideas for solutions, you probably don’t need to read it.)
If you want to know why I’m going through a form–not essential to the question–it’s because I’ve got something like this:
class Profile(models.Model):
user = models.ForeignKey(auth.models.User)
value_to_company = models.IntegerField()
class ValueField(forms.Field):
def to_python(self, value):
vals = {'high': 0,
'mid': 1}
return vals[value]
class ProfileForm(forms.ModelForm):
value_to_company = ValueField()
class Meta:
model = Profile
That is, I’m doing type api-to-internal-representation-coercion in my forms already and I’d like to continue using that.
I could reimplement the forms.is_valid() loop, just checking for the fields on the form that already exist, something hacky like:
# replaces `if not profile.is_valid()` above:
errors = []
for field in request.POST.iterkeys():
if field in profile.fields:
profile.fields[field].to_python()
if not profile.fields['field'].clean():
errors.append #something
(I haven’t actually looked at the logic internal logic, so I know that’s wrong, but you get the idea.)
You likely just need to add
exclude = ('user',)to your form. The forms instance mostly determines initial values, if your form includes the user field, but that field is posted with a blank value it will try to blank out the user field, resulting in the error.