Reputation: 115
I am trying to change a value in a post request but am getting the following error:
IntegrityError: null value in column "owner" violates not-null constraint
DETAIL: Failing row contains (30, 123, G, null) <--> (index, number, type, owner)
The form itself:
<form method="post">
{% csrf_token %}
{{form.number}}
{{form.type}}
<input type="hidden" value="{{variable}}" name="owner">
<button type="submit">Save</button>
</form>
The request.POST data:
<QueryDict: {'csrfmiddlewaretoken': ['TN3yNiGcvAso6V1UYZDHpyIQ1sNTMqDICPSqX2sftVpZfX6drambOkzoGBECLKcN'], 'number': ['123'], 'type': ['G'], 'owner': ['']}>
To modify the data:
class NodeCreateView(CreateView):
model = Node
form_class = NodeCreateForm
...
def post(self, request, **kwargs):
request.POST = request.POST.copy()
request.POST['owner'] = 2
return super(NodeCreateView, self).post(request, **kwargs)
The updated POST data:
<QueryDict: {'csrfmiddlewaretoken': ['TN3yNiGcvAso6V1UYZDHpyIQ1sNTMqDICPSqX2sftVpZfX6drambOkzoGBECLKcN'], 'number': ['123'], 'type': ['G'], 'owner': [2]}>
Where am I going wrong?
Upvotes: 2
Views: 5762
Reputation: 308769
You don't have to include the owner as a hidden input, or modify the post data like this.
First, exclude the owner from your form:
class NodeCreateForm(forms.ModelForm):
class Meta:
model = Node
exclude = ['owner']
Then in your view, override the form_valid
method, and set the owner_id
on the instance:
class NodeCreateView(CreateView):
model = Node
form_class = NodeCreateForm
def form_valid(self, form):
form.instance.owner_id = 2
return super(NodeCreateView, self).form_valid(form)
I'm assuming owner is a foreign key, otherwise set form.instance.owner = 2
.
Upvotes: 7
Reputation:
for your case better way to override get_form_kwargs
, for example:
def get_form_kwargs(self):
kwargs = super(NodeCreateView).get_form_kwargs()
kwargs['data'].update({'owner': 2})
return kwargs
Upvotes: 1
Reputation: 844
You're correctly mutating request.POST
by using copy()
, but passing the modified request object into super().post()
is misleading. If you follow the call chain back to where the view is actually accessing the request object, it's not using your modified request, it's using the un-modified request as self.request
. See here.
There is probably a better way to accomplish whatever it is you're doing, but if it's nothing permanent, you can just override get_form_kwargs()
in your NodeCreateView
.
Upvotes: 2