Reputation: 344
When I click "save" on the Update page (http://127.0.0.1:8000/account/15/update) I get
[19/Mar/2021 13:47:18] "GET /account/15/update HTTP/1.1" 200 2311
Method Not Allowed (POST): /account/15/
Method Not Allowed: /account/15/
[19/Mar/2021 13:47:24] "POST /account/15/ HTTP/1.1" 405 0
The database record does not get updated, so it looks like something fails silently. And looking at the error message it looks like we end up attempting a POST on the Account Detail page instead of the Account Update page - how did that happen?
Here's my Accounts\urls.py
from django.urls import path
from .views import (
AccountCreateView,
AccountListView,
AccountDetailView,
AccountUpdateView,
AccountDeleteView
)
app_name = 'account'
urlpatterns = [
path('', AccountListView.as_view(), name='account-list'),
path('create/', AccountCreateView.as_view(), name='account-create'),
path('<int:pk>/', AccountDetailView.as_view(), name='account-detail'),
path('<int:pk>/update', AccountUpdateView.as_view(), name='account-update'),
path('<int:pk>/delete', AccountDeleteView.as_view(), name='account-delete'),
]
Here's my Accounts\views.py
from django.shortcuts import render, get_object_or_404, redirect
from django.views.generic import (
CreateView,
DetailView,
ListView,
UpdateView,
DeleteView
)
from .forms import AccountForm
from .models import Account
class AccountCreateView(CreateView):
form_class = AccountForm
template_name = 'Accounts/account_create.html'
queryset = Account.objects.all().order_by("-pk")
def form_valid (self, form):
return super().form_valid(form)
class AccountDetailView(DetailView):
def get_object(self):
account_id = self.kwargs.get("pk")
return get_object_or_404(Account, account_id=account_id)
class AccountUpdateView(UpdateView):
form_class = AccountForm
template_name = 'Accounts/account_create.html'
def get_object(self):
account_id = self.kwargs.get("pk")
return get_object_or_404(Account, account_id=account_id)
def form_valid (self, form):
return super().form_valid(form)
And here's my Accounts\account_create.html (which I use both for create and update)
{% extends 'base.html' %}
{% block content %}
<h1>Account Create/Update Page for {{ request.user }} </h1>
This is the InApp Account Create/Update Page<p/>
<form action="." method='POST' enctype="multipart/form-data"> {% csrf_token %}
<table id="accountdetail">
{{ form.as_table }}
</table>
<p/>
<input type="submit" value="Save"/>
<button onclick="location.href='/account'" type="button">Cancel</button>
</form>
{% endblock %}
What am I missing? Thanks.
Upvotes: 1
Views: 981
Reputation: 66
Your form in the HTML is explicitly sending POST data to ".":
<form action="." method='POST' enctype="multipart/form-data">
so I believe /account/15/update
becomes /account/15
, like moving one directory up. If you really want to use the same template, you could try something like:
{% if "update" in request.get_full_path %}
<form action="{% url 'account-update' account.id %}" method="PUT">
{% else %}
<form action="{% url 'account-create' account.id %}" method="POST" enctype="multipart/form-data">
Also, note that the enctype attribute can only be used with a method="POST"
Upvotes: 2