TypeError: post() got an unexpected keyword argument
TypeError: post() got an unexpected keyword argument
我正在尝试创建一个可以直接与用户交流的简单博客。每个用户每个月都会有一个博客 post 由管理员 post 编辑,他们可以在博客上发表评论以进行交流。工作流程如下:
管理员登录站点 -> 管理员会看到所有可用的用户。 -> 管理员点击一个用户 -> 如果该用户有当月的 post,则显示 post -> 否则创建新的 post.
这是我的:
blog/urls.py:
from django.urls import path
from .views import MessageThread, CreateThread
urlpatterns = [
path('user_thread/<int:user_id>', MessageThread.as_view(), name='message_thread'),
path('create_thread/<int:user_id>', CreateThread.as_view(), name='create_thread'),
]
blog/models.py:
from django.db import models
from django.contrib.auth.models import User
class Post(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=200)
text = models.TextField(max_length=9001)
posted_for = models.ForeignKey(User, related_name='posted_for', on_delete=models.CASCADE)
published_date = models.DateTimeField(blank=True, null=True)
def __str__(self):
return self.title
blog/forms.py:
from django.forms import models
from .models import Post
class CreateThreadForm(models.ModelForm):
class Meta:
model = Post
fields = ['title', 'text']
blog/views.py:
from .forms import CreateThreadForm
from django.shortcuts import render, redirect
from django.views.generic import TemplateView
from datetime import datetime
from django.contrib.auth.models import User
class CreateThread(TemplateView):
template_name = 'blog/create_thread.html'
def get(self, request, *args, **kwargs):
return render(request, self.template_name, {'form': CreateThreadForm(), 'user_id': self.kwargs['user_id']})
def post(self, request):
if 'comfirm_post' in request.POST:
form = CreateThreadForm(request.POST)
if form.is_valid():
post_details = form.save(commit=False)
post_details.author = request.user
post_details.posted_for = User.objects.get(id=request.POST['user_id'])
post_details.published_date = datetime.now()
form.save()
messages.success(request, "Successfully created post")
return redirect('message_thread', user_id=request.POST['user_id'])
messages.error(request, 'Something went wrong')
return redirect('create_thread', user_id=request.POST['user_id'])
blog/create_thread.html:
{% extends 'navbar.html' %}
{% block content %}
<h1>Create New Thread</h1>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" name="comfirm_post">Create Thread</button>
</form>
{% endblock %}
问题是它甚至没有进入 CreateThread
class 中的 post() 函数。它只是抛出一个错误 post() got an unexpected keyword argument 'user_id'
。这是错误的完整引用:
Internal Server Error: /blog/create_thread/4
Traceback (most recent call last):
File "C:\Projects-2-1\venv\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\Projects-2-1\venv\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Projects-2-1\venv\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Projects-2-1\venv\lib\site-packages\django\views\generic\base.py", line 71, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Projects-2-1\venv\lib\site-packages\django\views\generic\base.py", line 97, in dispatch
return handler(request, *args, **kwargs)
TypeError: post() got an unexpected keyword argument 'user_id'
[27/Aug/2019 16:04:02] "POST /blog/create_thread/4 HTTP/1.1" 500 75548
我不知道这个 user_id 是从哪里来的。我曾尝试将 user_id 作为表单的隐藏输入传递,我尝试更改操作以传递 action={% url 'create_thread' user_id %}
之类的 user_id 但这根本不起作用。
您的 URL 模式中有 user_id
,
path('create_thread/<int:user_id>', ...
因此你的 post
方法应该采用 user_id
,你应该使用 user_id
而不是 request.POST['user_id']
:
def post(self, request, user_id):
...
post_details.posted_for = User.objects.get(id=user_id)
或者,您可以接受 *args
和 **kwargs
,并从 kwargs
或 self.kwargs
.
获取 user_id
def post(self, request, *args, **kwargs):
...
post_details.posted_for = User.objects.get(id=self.kwargs['user_id'])
因为你的 url 有一个 user_id
,你需要在 post
方法中使用它:
class CreateThread(TemplateView):
template_name = 'blog/create_thread.html'
def get(self, request, *args, **kwargs):
return render(request, self.template_name, {'form': CreateThreadForm(), 'user_id': self.kwargs['user_id']})
def post(self, request, <b>user_id</b>):
if 'comfirm_post' in request.POST:
form = CreateThreadForm(request.POST)
if form.is_valid():
post_details = form.save(commit=False)
post_details.author = request.user
post_details.posted_for = User.objects.get(id=<b>user_id</b>)
post_details.published_date = datetime.now()
form.save()
messages.success(request, "Successfully created post")
return redirect('message_thread', user_id=<b>user_id</b>)
messages.error(request, 'Something went wrong')
return redirect('create_thread', user_id=<b>user_id</b>)
然而,您可以在此处使用 CreateView
[Django-doc],这可以减少样板代码的数量:
from django.views.generic.edit import <b>CreateView</b>
from django.contrib.messages.views import <b>SuccessMessageMixin</b>
from django.urls import reverse
class CreateThread(<b>SuccessMessageMixin, CreateView</b>):
template_name = 'blog/create_thread.html'
<b>form_class = CreateThreadForm</b>
model = Post
<b>success_message = 'Successfully created post'</b>
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)
context['user_id'] = self.kwargs['user_id']
return context
def get_success_url(self):
return reverse('message_thread', kwargs={'user_id': self.kwargs['user_id']})
def form_valid(self, form):
form.instance.author = request.user
form.instance.posted_for_id = self.kwargs['user_id']
form.instance.published_date = datetime.now()
return super().form_valid(form)
def post(self, request, *args, **kwargs):
if 'comfirm_post' in request.POST:
return super().post(request, *args, **kwargs)
messages.error(request, 'Something went wrong')
return redirect('create_thread', user_id=user_id)
我正在尝试创建一个可以直接与用户交流的简单博客。每个用户每个月都会有一个博客 post 由管理员 post 编辑,他们可以在博客上发表评论以进行交流。工作流程如下:
管理员登录站点 -> 管理员会看到所有可用的用户。 -> 管理员点击一个用户 -> 如果该用户有当月的 post,则显示 post -> 否则创建新的 post.
这是我的:
blog/urls.py:
from django.urls import path
from .views import MessageThread, CreateThread
urlpatterns = [
path('user_thread/<int:user_id>', MessageThread.as_view(), name='message_thread'),
path('create_thread/<int:user_id>', CreateThread.as_view(), name='create_thread'),
]
blog/models.py:
from django.db import models
from django.contrib.auth.models import User
class Post(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=200)
text = models.TextField(max_length=9001)
posted_for = models.ForeignKey(User, related_name='posted_for', on_delete=models.CASCADE)
published_date = models.DateTimeField(blank=True, null=True)
def __str__(self):
return self.title
blog/forms.py:
from django.forms import models
from .models import Post
class CreateThreadForm(models.ModelForm):
class Meta:
model = Post
fields = ['title', 'text']
blog/views.py:
from .forms import CreateThreadForm
from django.shortcuts import render, redirect
from django.views.generic import TemplateView
from datetime import datetime
from django.contrib.auth.models import User
class CreateThread(TemplateView):
template_name = 'blog/create_thread.html'
def get(self, request, *args, **kwargs):
return render(request, self.template_name, {'form': CreateThreadForm(), 'user_id': self.kwargs['user_id']})
def post(self, request):
if 'comfirm_post' in request.POST:
form = CreateThreadForm(request.POST)
if form.is_valid():
post_details = form.save(commit=False)
post_details.author = request.user
post_details.posted_for = User.objects.get(id=request.POST['user_id'])
post_details.published_date = datetime.now()
form.save()
messages.success(request, "Successfully created post")
return redirect('message_thread', user_id=request.POST['user_id'])
messages.error(request, 'Something went wrong')
return redirect('create_thread', user_id=request.POST['user_id'])
blog/create_thread.html:
{% extends 'navbar.html' %}
{% block content %}
<h1>Create New Thread</h1>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" name="comfirm_post">Create Thread</button>
</form>
{% endblock %}
问题是它甚至没有进入 CreateThread
class 中的 post() 函数。它只是抛出一个错误 post() got an unexpected keyword argument 'user_id'
。这是错误的完整引用:
Internal Server Error: /blog/create_thread/4
Traceback (most recent call last):
File "C:\Projects-2-1\venv\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\Projects-2-1\venv\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Projects-2-1\venv\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Projects-2-1\venv\lib\site-packages\django\views\generic\base.py", line 71, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Projects-2-1\venv\lib\site-packages\django\views\generic\base.py", line 97, in dispatch
return handler(request, *args, **kwargs)
TypeError: post() got an unexpected keyword argument 'user_id'
[27/Aug/2019 16:04:02] "POST /blog/create_thread/4 HTTP/1.1" 500 75548
我不知道这个 user_id 是从哪里来的。我曾尝试将 user_id 作为表单的隐藏输入传递,我尝试更改操作以传递 action={% url 'create_thread' user_id %}
之类的 user_id 但这根本不起作用。
您的 URL 模式中有 user_id
,
path('create_thread/<int:user_id>', ...
因此你的 post
方法应该采用 user_id
,你应该使用 user_id
而不是 request.POST['user_id']
:
def post(self, request, user_id):
...
post_details.posted_for = User.objects.get(id=user_id)
或者,您可以接受 *args
和 **kwargs
,并从 kwargs
或 self.kwargs
.
user_id
def post(self, request, *args, **kwargs):
...
post_details.posted_for = User.objects.get(id=self.kwargs['user_id'])
因为你的 url 有一个 user_id
,你需要在 post
方法中使用它:
class CreateThread(TemplateView):
template_name = 'blog/create_thread.html'
def get(self, request, *args, **kwargs):
return render(request, self.template_name, {'form': CreateThreadForm(), 'user_id': self.kwargs['user_id']})
def post(self, request, <b>user_id</b>):
if 'comfirm_post' in request.POST:
form = CreateThreadForm(request.POST)
if form.is_valid():
post_details = form.save(commit=False)
post_details.author = request.user
post_details.posted_for = User.objects.get(id=<b>user_id</b>)
post_details.published_date = datetime.now()
form.save()
messages.success(request, "Successfully created post")
return redirect('message_thread', user_id=<b>user_id</b>)
messages.error(request, 'Something went wrong')
return redirect('create_thread', user_id=<b>user_id</b>)
然而,您可以在此处使用 CreateView
[Django-doc],这可以减少样板代码的数量:
from django.views.generic.edit import <b>CreateView</b>
from django.contrib.messages.views import <b>SuccessMessageMixin</b>
from django.urls import reverse
class CreateThread(<b>SuccessMessageMixin, CreateView</b>):
template_name = 'blog/create_thread.html'
<b>form_class = CreateThreadForm</b>
model = Post
<b>success_message = 'Successfully created post'</b>
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)
context['user_id'] = self.kwargs['user_id']
return context
def get_success_url(self):
return reverse('message_thread', kwargs={'user_id': self.kwargs['user_id']})
def form_valid(self, form):
form.instance.author = request.user
form.instance.posted_for_id = self.kwargs['user_id']
form.instance.published_date = datetime.now()
return super().form_valid(form)
def post(self, request, *args, **kwargs):
if 'comfirm_post' in request.POST:
return super().post(request, *args, **kwargs)
messages.error(request, 'Something went wrong')
return redirect('create_thread', user_id=user_id)