I am adding a new row instead of make changes in a existing row in my DB

I am trying to save my form in my data base. But my code adds a new row instead of save changes to the existing one. where is my mistake?

view.py

    def settings(request):
        error = ''
        if request.method == 'POST':
            new_form = TrafficSourcesForm(request.POST)
            if new_form.is_valid():
                new_form.save()
    
    
    
            else:
                error = 'Something went wrong!'
new_form = TrafficSourcesForm()
    forms = [TrafficSourcesForm(instance=x) for x in TrafficSources.objects.all()]

   
    return render(request, 'mainpage/dashboard.html', {'new_form': new_form, 'forms': forms, 'error': error})

template

<div class="table table-striped table-hover">

            <div class="table-row">
                <th style="width: 42%">Name</th>
                <th style="width: 43%">Token</th>
                <th style="width: 15%">Action</th>
            </div>
        {% for form in forms %}
            <div class="table-row">
                <form method="POST">
                {% csrf_token %}
                <div class="table-cell">{{ form.name }}</div>
                <div class="table-cell">{{ form.token }}</div>
                <div class="table-cell"><button class="btn btn-lg btn-success w-100"">Save</button></div>
                </form>
            </div>
        </div>

If its not clear: I am showing all the table from my databese on the page. I want to edit them and save again to the database.

Id recommend getting the specific object you want to modify. Ex. traffic_source = TrafficSources.objects.get(id=<id_here>)

Because you are using POST data and form to create a new instance on every request:

...
if request.method == 'POST':
    new_form = TrafficSourcesForm(request.POST)
    if new_form.is_valid():
        new_form.save()
...

To edit an object, you first need to retrieve the instance, which is normally done using its unique identifier (pk). Although normally you would send this ID using the url dispatcher captured value. I am using a hidden field in this case:

mainpage/dashboard.html

<body>
    {% if forms %}
        <table class="table table-striped table-hover">
            <thead>
                <tr>
                    <th style="width: 42%">Name</th>
                    <th style="width: 43%">Token</th>
                    <th style="width: 15%">Action</th>
                </tr>
            </thead>

            <tbody>
                {% for form in forms %}
                <form method="POST">
                    {% csrf_token %}
                    <tr>
                        <td>{{ form.name }}</td>
                        <td>{{ form.token }}</td>
                        <input type="hidden" value="{{ form.instance.pk }}" name="id">
                        <td class="table-cell"><button class="btn btn-lg btn-success w-100">Save</button></td>
                    </tr>
                </form>
                {% endfor %}
            </tbody>
        </table>
    {% endif %}

    <form method="POST">
        {% csrf_token %}
        {{new_form.as_p}}
        <div class="table-cell"><button class="btn btn-lg btn-success w-100">Create</button></div>
    </form>
</body>

views.py

def settings(request):
    error = ''
    if request.method == 'POST':
        new_form = TrafficSourceForm(request.POST)
        pk = request.POST.get('id')
        
        if new_form.is_valid():
            if pk:
                TrafficSource.objects.filter(id=pk).update(**new_form.cleaned_data)
            else:
                TrafficSource.objects.create(**new_form.cleaned_data)
                
        else:
            error = 'Something went wrong!'
    new_form = TrafficSourceForm()
    forms = [TrafficSourceForm(instance=x) for x in TrafficSource.objects.all()]
 
    return render(request, 'mainpage/dashboard.html', {'new_form': new_form, 'forms': forms, 'error': error})
Back to Top