Home > Mobile >  Update is creating new entry rather than updating it
Update is creating new entry rather than updating it

Time:11-30

I have a model where users save their details. I am able to save user details through the template I have created. But whenever I edit the data to update it, a new entry is created in database

models.py

class User(AbstractUser):
    pass
    def __str__(self):
        return self.username

class Detail(models.Model):
    """
    This is the one for model.py
    """
    username = models.ForeignKey(User, on_delete=models.CASCADE, null=True, default="")
    matricno = models.CharField(max_length=9, default="")
    email = models.EmailField(default="")
    first_name = models.CharField(max_length=200, default="")
    last_name = models.CharField(max_length=255, default="")

    class Meta:
        verbose_name_plural = "Detail"

    def __str__(self):
        return self.first_name  " " self.last_name

views.py

@login_required(login_url="signin")
def details(request):
    form = Details()
    if request.method == "POST":
        form = Details(request.POST)
        if form.is_valid():
            detail = form.save(commit=False)
            detail.username = request.user
            detail.save()
            return redirect(success, pk=detail.pk)
    else:
        form = Details(initial={"matricno":request.user.username})
    return render(request, "details.html", {"form":form})

def success(request,pk):
    return render(request, "success.html", {"pk":pk})

def updatedetails(request, pk):
    detail = Detail.objects.get(id=pk)
    form = Details(instance=detail)
    if request.method == "POST":
        form = Details(request.POST, instance=detail)
        if form.is_valid():
            form.save()
            return redirect(success, pk=detail.pk)
    return render(request, "details.html", {"form":form})

urls.py

from django.urls import path

from . import views

urlpatterns = [
    path("", views.index, name="index"),
    path("details/", views.details, name="details"),
    path("success/<int:pk>/", views.success, name="success"),
    path("edit/<int:pk>/", views.updatedetails, name="updatedetails"),
]

The template used for rendering out the form to input user details goes as follows

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>details</title>
</head>
<body>
    <form action="/details/" method="POST">
        {% csrf_token %}
        {% if request.user.is_authenticated %}
        <p>
            {{form.matricno}}
        </p>

        <p>
            {{form.email}}
        </p>

        <p>
            {{form.first_name}}
        </p>

        <p>
            {{form.last_name}}
        </p>

        <p>
            <input type="submit" value="Create">
        </p>
        {% endif %}
        <div>
            <a href="/signout/"><input type="button" value="SignOut"></a>
        </div>
    </form>
</body>
</html>

After a user enters their details and it is saved to database successfully, it redirect to a success where their is a link that takes you back to the other page to edit the data you inputed and it goes as follows.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Success</title>
</head>
<body>
    <h1>Thank You for Filling Out the Form</h1>
    <p><a href="{% url 'updatedetails' pk %}">Click Here To Edit</a></p>
</body>
</html>

My problem now is that whenever i click on the link to edit, and i edit the details i have entered, it creates a new entry in database rather than updating previous data.

CodePudding user response:

You need to POST to the edit view, so:

<form action="{% url 'updatedetails' pk=form.instance.pk %}" method="POST">
    ...
</form>

You should thus make two templates: one to create data, and one to edit data.

  • Related