TypeError:post()获得了意外的关键字参数

时间:2019-08-27 12:07:29

标签: django django-models django-class-based-views

我正在尝试创建一个简单的博客,在这里我可以直接与用户交流。每个用户每个月都会有一个由Admin发布的博客帖子,他们可以对此发表评论以进行交流。工作流程如下:

管理员登录到站点->向管理员显示所有可用用户。 ->管理员点击用户->如果该用户有当月的帖子,则显示该帖子->其他创建新帖子。

这是我所拥有的:

blog / urls.py

Amount = 0

blog / models.py:

Line = 3

blog / forms.py:

const Apify = require('apify');
const cheerio = require('cheerio');
const requestPromised = require('request-promise-native');

Apify.main(async () => {

    const xml = await requestPromised({
        url: 'https://www.website.com/sitemap1.xml’, // <- This part needs to accept input of about 600 sitemap.xml urls in total

        headers: {
        'User-Agent': 'curl/7.54.0'
        }
     });

    // Parse sitemap and create RequestList from it
    const $ = cheerio.load(xml);
    const sources = [];
    $('loc').each(function (val) {
        const url = $(this).text().trim();
        sources.push({
            url,
            headers: {
                // NOTE: Otherwise the target doesn't allow to download the page!
                'User-Agent': 'curl/7.54.0',
            }
        });
    });

    const requestList = new Apify.RequestList({
        sources,
    });
    await requestList.initialize();

    // Crawl each page from sitemap
    const crawler = new Apify.CheerioCrawler({
        requestList,
        handlePageFunction: async ({ $, request }) => {

            await Apify.pushData({
                url: request.url
            });
        },
    });

    await crawler.run();
    console.log('Done.');
});

blog / views.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 / create_thread.html:

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

问题在于它甚至没有进入from django.forms import models from .models import Post class CreateThreadForm(models.ModelForm): class Meta: model = Post fields = ['title', 'text'] 类的post()函数中。它只是抛出一个错误,说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']) 。这是错误的完整记录:

{% 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 %}

我不知道该用户名来自何处。我尝试将user_id作为表单的隐藏输入进行传递,我尝试将操作更改为传递CreateThread之类的user_id,但这根本不起作用。我觉得这将是非常小的事情,但是经过数小时的搜索后我还是无法解决。任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:2)

您的网址格式中有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,并从user_idkwargs提取self.kwargs

def post(self, request, *args, **kwargs):
    ...
    post_details.posted_for = User.objects.get(id=self.kwargs['user_id'])

答案 1 :(得分:2)

由于您的网址包含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, user_id):

        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=user_id)
                post_details.published_date = datetime.now()
                form.save()

                messages.success(request, "Successfully created post")
                return redirect('message_thread', user_id=user_id)

        messages.error(request, 'Something went wrong')
        return redirect('create_thread', user_id=user_id)

不过,您可以在此处使用CreateView [Django-doc],这样可以减少样板代码的数量:

from django.views.generic.edit import CreateView
from django.contrib.messages.views import SuccessMessageMixin
from django.urls import reverse

class CreateThread(SuccessMessageMixin, CreateView):
    template_name = 'blog/create_thread.html'
    form_class = CreateThreadForm
    model = Post
    success_message = 'Successfully created post'

    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)