0

i want the form to be prepopulated with data when i am editing the form

views.py

def edit_task(request, post_id):
    post = Post.objects.get(id=post_id)
    form = TaskForm(request.POST, instance=post)
    if request.method == 'POST':
        print(request.POST)
        form = TaskForm(request.POST, instance=post)
        if form.is_valid():
            form.save()
            return redirect('task')
    context = {'form': form}
    return render(request, 'List/add_task.html', context)

add_task.html

{% extends "List/Home.html" %}
{% block content %}

<form action="" method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit">
    
</form>

{% endblock content %}
Naveed naseer
  • 85
  • 1
  • 10

2 Answers2

1

you can populate this form with data, providing initial

def edit_task(request, post_id):
    post = Post.objects.get(id=post_id)
    form = TaskForm(request.POST if request.POST else None, instance=post, initial={
        'initial_field_name_1': 'initial_field_value_1',
...
        'initial_field_name_n': 'initial_field_value_n',
    })
    if request.method == 'POST':
        print(request.POST)
        if form.is_valid():
            form.save()
            return redirect('task')
    context = {'form': form}
    return render(request, 'List/add_task.html', context)
Andrey Maslov
  • 1,396
  • 1
  • 8
  • 10
  • sorry i am new to django can u tell me what is 'initial_field_name_1 and 'initial_field_value_1', – Naveed naseer Jul 10 '20 at 15:22
  • `initial` isn't useful for model forms when `instance` is provided - the form will use the values from the instance instead. – Alasdair Jul 10 '20 at 16:50
  • initial_field_name_1 and initial_field_value_1 is name and value of field that you want to provide default values. but as mentioned above, this could be done only with extra fields, that you add to form(other fields would be filled by values stored in database model) – Andrey Maslov Jul 10 '20 at 21:34
1

Think carefully about how you instantiate forms. At the moment, you are using the same code TaskForm(request.POST, instance=post) for GET and POST requests:

def edit_task(request, post_id):
    post = Post.objects.get(id=post_id)
    form = TaskForm(request.POST, instance=post)
    if request.method == 'POST':
        print(request.POST)
        form = TaskForm(request.POST, instance=post)
        ...

But request.POST is empty for GET requests, so you'll get an empty form with errors when you load the form with a GET request.

You can fix it by removing request.POST for GET requests

def edit_task(request, post_id):
    post = Post.objects.get(id=post_id)
    # Instantiate form without any data
    form = TaskForm(instance=post)
    if request.method == 'POST':
        print(request.POST)
        # replace the form for POST requests
        form = TaskForm(request.POST, instance=post)
        ...

It might be clearer to use if...else instead of replacing the form:

def edit_task(request, post_id):
    post = Post.objects.get(id=post_id)
    if request.method == 'POST':
        print(request.POST)
        # instantiate form for POST requests
        form = TaskForm(request.POST, instance=post)
        ...
    else:
        # instantiate the form for GET requests
        form = TaskForm(instance=post)
    context = {'form': form}
    return render(request, 'List/add_task.html', context)


Alasdair
  • 298,606
  • 55
  • 578
  • 516
  • oh now i get it i was using the post request for getting the form and thats why the form was empty. Well thanks for your help bro you really helped me alot also sorry for some dumb questions i am new to django. – Naveed naseer Jul 11 '20 at 05:50