William
William

Reputation: 115

Django - alter post data in CreateView

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

Answers (3)

Alasdair
Alasdair

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

user8060120
user8060120

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

mindcruzer
mindcruzer

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

Related Questions