Pierre de LESPINAY
Pierre de LESPINAY

Reputation: 46198

Django - Form bind data after initialization

I have a user model for which I'm trying to make a view that manages both create/update form rendering/post.

Here is the view that I did for now

def user_edit(request, user_id=None):
    obj = {}
    status = 200

    if user_id:
        user = get_object_or_404(User, pk=user_id)
    else:
        user = User()

    user_form = UserForm(instance=user, prefix='user')

    if request.method == 'POST':
        user_form = UserForm(request.POST, instance=user, prefix='user')
        if user_form.is_valid():
            user_form.save()
        else:
            status = 406

    obj['user_form'] = user_form
    return render(request, 'user/edit.html', obj, status=status)

This works fine, but as you can see, my user_form is initialized 2 times. In order to make this more DRY, at POST time I'd like to update the form definition instead of redefining it. Something like:

    if request.method == 'POST':
        user_form.data = request.POST
        user_form.prefix = 'user'

But I can't make this work. So 2 questions:

Upvotes: 0

Views: 2321

Answers (2)

karthikr
karthikr

Reputation: 99660

I would just restructure a couple of lines this way:

def user_edit(request, user_id=None):

    status = 200

    if user_id:
        user = get_object_or_404(User, pk=user_id)
    else:
        user = User()

    user_form = UserForm(request.POST or None, instance=user, prefix='user')

    if request.method == 'POST':
        if user_form.is_valid():
            user_form.save()
        else:
            status = 406

    return render(request, 'user/edit.html', {'form': user_form}, status=status)

Sometimes, it makes sense to duplicate may be 1 line of code to keep it readable.

Upvotes: 3

Tomáš Diviš
Tomáš Diviš

Reputation: 1066

You should use if condition like this to initialize form only once:

def contact(request):
    if request.method == 'POST': # If the form has been submitted...
        form = ContactForm(request.POST) # A form bound to the POST data
        if form.is_valid(): # All validation rules pass
            # Process the data in form.cleaned_data
            # ...
            return HttpResponseRedirect('/thanks/') # Redirect after POST
    else:
        form = ContactForm() # An unbound form

    return render(request, 'contact.html', {
        'form': form,
    })

Taken from documentation of django. If you are new to Python, it may seem strange to define a variable in if..else statement, but it is pretty common and valid way in Python.

Upvotes: 0

Related Questions