Как я могу получить доступ к первичному ключу в теге шаблона

Я пытаюсь создать представление обновления, которое позволяет пользователям обновлять данные. Я пытаюсь получить доступ к данным, используя первичные ключи. Моя проблема в том, что я не знаю синтаксиса для реализации этого.

views.py

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)
    return render(request, "details.html", {"form":form})

urls.py

from django.urls import path

from . import views

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

мой html-шаблон

<!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="/edit/{{request.detail.id}}/">Click Here To Edit</a></p>
</body>
</html>

Итак, я пытаюсь понять, как вызвать первичный ключ в моем шаблоне

Попробуйте использовать

href="{% url 'updatedetails' pk=request.detail.id %}"

Дайте мне знать, если это сработает. Это будет искать имя пути updatedetails, расположенное в ваших urlpatterns, и предоставлять id в качестве ключа. Я тоже новичок в этом деле, поэтому надеюсь, что это поможет и будет правильным.

Сначала я бы рекомендовал вам изменить <str:pk> на <int:pk> в updatedetails пути, чтобы urls.py имел вид:

from django.urls import path

from . import views

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

Во-вторых, я бы рекомендовал вам использовать get_object_or_404() вместо get(), а также, если вы правильно видите, вам не хватает "" в redirect(success), что должно быть redirect("success"), поэтому views.py должен быть:

from django.shortcuts import get_object_or_404

def updatedetails(request, pk):
    detail = get_object_or_404(Detail,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")
    return render(request, "details.html", {"form":form})

Тогда в шаблоне вы можете использовать url tags и передать pk в updatedetails представление как:

<!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' request.detail.id %}">Click Here To Edit</a></p>
</body>
</html>

Ответ на первоначальный вопрос

Как я могу получить доступ к первичному ключу в теге шаблона?

Ну, вы должны передать его в представление, которое отображает шаблон, либо через контекст, либо в данном случае, поскольку он нужен на странице успеха, на которую вы попадаете через редирект, отправьте его как параметр в вашем редиректе.

Во-вторых, если вы пытаетесь создать форму из модели, то используйте ModelForm. Этого нельзя сделать, просто установив переменную формы равной экземпляру модели. Для этого нужно создать файл forms.py:

# forms.py

from django.forms import ModelForm
from .models import Detail

class DetailForm(ModelForm):
    class Meta:
        model = Detail
        # Include below the fields from the Detail model you
        # would like to include in your form
        fields = ['username', 'matricno', 'email', 'first_name', 'last_name', ]

Затем в ваших представлениях вы можете получить доступ к этой форме:

#views.py

from .models import Detail
from .forms import DetailForm

def success(request, pk):
    # NOTE that here you must receive the pk
    return render(request, "success.html", {'pk': pk})

@login_required(login_url="signin")
def details(request):
    form = DetailForm()
    if request.method == "POST":
        form = DetailForm(request.POST)
        if form.is_valid():
            detail = form.save(commit=False)
            detail.username = request.user
            detail.save()
            # NOTE: here you can send the detail primary key, pk, or id
            # to the success view where you are trying to use it
            return redirect('success', pk=detail.pk)
    else:
        form = Details(initial={"matricno": request.user.username})
    return render(request, "details.html", {"form": form})

def updatedetails(request, pk):
    detail = Detail.objects.get(id=pk)
    form = DetailForm(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})

Обратите внимание, как вы можете отправить первичный ключ в шаблон success в редиректе. Это и есть ответ на первоначальный вопрос.

Теперь вы можете получить доступ к первичному в вашем шаблоне просто:

<!--html template -->
<!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>

Поскольку представление success необходимо изменить, чтобы получить первичный ключ, мы должны изменить urls.py так, чтобы он мог получить его:

# urls.py
from django.urls import path

from . import views

urlpatterns = [
    path("details/", views.details, name="details"),
    path("success/<int:pk>/", views.success, name="success"),
    path("edit/<int:pk>/", views.updatedetails, name="updatedetails"),
]
Вернуться на верх