'How do I prevent a duplicate entry on refresh for django model?

I am still learning Django and recently discovered that when I refresh my page it does a duplicate entry and was wondering how I might avoid this or link the function to the button possibly.

Here is my views.py function

def basketballPickup(request):
# displays page and Pickup model
form = PickupForm(data=request.POST or None)
posts = Pickup.games.all()
if request.method == 'POST':
    form_valid = form.is_valid()
    if form_valid:
        instance = form.save(commit=False)
        instance.save()
content = {'form': form, 'posts': posts}
return render(request, 'Basketball/Basketball_Pickup.html', content)

and here is my HTML template

    {% extends "Basketball/Basketball_base.html" %}

{% block content %}

<form method="POST">
    {% csrf_token %}
    {{form.as_p}}
    <button type="submit" name="Save_Pickup">Save Pickup Game</button>
</form>
<div id="pickup_table">
    <table>
    {% for i in posts %}
        <tr>
        <th><p>Position:<p>{{ i.position}}</th>
        <th><p>Date:</p>{{ i.date}}</th>
        <th><p>Points:</p>{{ i.points}}</th>
        <th><p>Assists:</p>{{ i.assists}}</th>
        <th><p>Rebounds:</p>{{ i.rebounds}}</th>
        <th><p>Steals:</p>{{ i.steals}}</th>
        <th><p>Blocks:</p>{{ i.blocks}}</th>
       <th><p>Turnovers:</p>{{ i.turnovers}}</th>
        </tr>
    {% endfor %}
    </table>
</div>

{% endblock %}

Here is the models.py I have the model stored in

position_choices = (
    ('pg', 'Point Guard'),
    ('sg', 'Shooting Guard'),
    ('sf', 'Small Forward'),
    ('pf', 'Power Forward'),
    ('c', 'Center')
)

class Pickup(models.Model):
    position = models.CharField(max_length=30, choices=position_choices, default='Point Guard')
    date = models.DateField(auto_now=True)
    points = models.PositiveIntegerField()
    assists = models.PositiveIntegerField()
    rebounds = models.PositiveIntegerField()
    steals = models.PositiveIntegerField()
    blocks = models.PositiveIntegerField()
    turnovers = models.PositiveIntegerField()


Solution 1:[1]

You need to use HttpResponseRedirect for preventing the duplicate entries, as stated in docs.

An Excerpt from the django-doc about POST request.

You should always return an HttpResponseRedirect after successfully dealing with POST data. This tip isn’t specific to Django; it’s good web development practice in general.

Here, I assumed that you are using all of your Pickup model's fields in your custom PickupForm, so I am saving data with reference to all fields, if you have written less fields to be submitted by the user so kindly, remove that field while saving the data, it would work or you kindly tell me.

You need also need to handle GET and POST conditions differenlty.

So, with your current code you need to do some modifications:

urls.py

urlpatterns=[
    ...
    ...
    path('success/',views.success,name='success')

]

views.py

from django.http import HttpResponseRedirect

def basketballPickup(request):
    # displays page and Pickup model
    if request.method == 'POST':  # here POST condition
        form = PickupForm(data=request.POST or None)
        if form.is_valid():
            position=form.cleaned_data['position']
            date=form.cleaned_data['date']
            points=form.cleaned_data['points']
            assists=form.cleaned_data['assists']
            rebounds=form.cleaned_data['rebounds']
            steals=form.cleaned_data['steals']
            blocks=form.cleaned_data['blocks']
            turnovers=form.cleaned_data['turnovers']
            data=Pickup(position=position,date=date,points=points,assists=assists,rebounds=rebounds,steals=steals,blocks=blocks,turnovers=turnovers)
            data.save()
            return HttpResponseRedirect('/success/')
    else:
        posts = Pickup.games.all()
        form = PickupForm()  # Here GET condition
    content = {'form': form, 'posts': posts}
    return render(request, 'Basketball/Basketball_Pickup.html', content)

def success(request):
    return render(request, 'Basketball/thanks.html')

thanks.html

<body>
<h3> The form successfully submitted. </h3>
</body>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1