首页 > 解决方案 > 我无法理解这个错误:TypeError: cannot convert dictionary update sequence element #0 to a sequence

问题描述

我被 new_entry 功能卡住了,这是 python book 速成课程中的一个项目,我多次尝试验证我的代码,但无法弄清楚为什么会出现此错误:

TypeError: cannot convert dictionary update sequence element #0 to a sequence

文件views.py

from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.urls import reverse

from .models import Topic
from .forms import TopicForm
from .forms import EntryForm

def index(request):
    return render(request, 'learning_logs/index.html')

def topics(request):
    # display all the topics
    topics = Topic.objects.order_by('date_added')
    context = {'topics': topics}
    return render(request, 'learning_logs/topics.html', context)

def topic(request, topic_id):
    # display entries pertaining to a topic
    topic = Topic.objects.get(id=topic_id)
    entries = topic.entry_set.order_by('-date_added')
    context = {'topic': topic, 'entries': entries}
    return render(request, 'learning_logs/topic.html', context)

def new_topic(request):
    # fill a new topic
    if request.method != 'POST':
        # No data submitted , create a blank form
        form = TopicForm()
    else:
        # post data submitted , process data
        form = TopicForm(request.POST)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect(reverse('learning_logs:topics'))

    context = {'form': form}
    return render(request, 'learning_logs/new_topic.html', context)

def new_entry(request, topic_id):
    # Enter a new entry into any topic
    topic = Topic.objects.get(id=topic_id)
    if request.method != 'POST':
        # NO data submitted , create a blank form
        form = EntryForm()
    else:
        # post data submitted , process data
        form = EntryForm(data=request.POST)
        if form.is_valid():
            new_entry = form.save(commit=False)
            new_entry.topic = topic
            new_entry.save()
            return HttpResponseRedirect(reverse('learning_logs:topic',
                                                args=[topic_id]))
    context = {'topic': topic, 'form': form}
    return render(request, 'learning_logs/new_entry.html', context)

文件urls.py

from django.urls import path
from . import views

app_name = 'learning_logs'
urlpatterns = [  # Homepage
    path('', views.index, name='index'),
    # topics
    path('topics', views.topics, name='topics'),
    # entries about each topic
    path('<topic_id>/topic/', views.topic, name='topic'),
    # page for adding a new topic
    path('new_topic/', views.new_topic, name='new_topic'),
    # adding entries
    path('new_entry/<int:topic_id>/', views.new_entry, name='new_entry'),
]

这就是我被 new_entry 功能卡住的地方,文件new_entry.html

{% extends "learning_logs/base.html" %}
{% block content %}

<p><a href="{% url 'learning_logs:topic' topic.id %}">{{ topic }}</a></p>
<p>New entry</p>
<form action="{% url 'learning_logs:new_entry' topic.id  %}" method="post">
    {% csrf_token %}
    {{form.as_p}}
    <button name="submit">add entry</button>
</form>

{% endblock content %}

文件forms.py

from django import forms
from .models import Topic
from .models import Entry

class TopicForm(forms.ModelForm):
    class Meta:
        model = Topic
        fields = ['text']
        labels = {'text': ''}

class EntryForm(forms.ModelForm):
    class Meta:
        model = Entry
        fields = ['text']
        labels = {'text': ''}
        widgets = {'text': forms.Textarea(attrs={'cols', 80})}

文件models.py

from django.db import models

class Topic(models.Model):
    # A topic that the user is learning about
    text = models.CharField(max_length=200)
    date_added = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        # Return the info as a string
        return self.text

class Entry(models.Model):
    # something specific learned about a topic
    topic = models.ForeignKey(Topic, on_delete=models.PROTECT)
    text = models.TextField()
    date_added = models.DateTimeField(auto_now_add=True)

    class Meta:
        verbose_name_plural = "entries"

    def __str__(self):
        # A representation of the data in string form
        if len(self.text) > 50:
            return str(self.text)[:50] + "...."``
        else:
            return self.text

标签: pythondjango

解决方案


我怀疑错误出在您的EntryForm.Meta.widgets; attrs应该是 a dict(应该写为{'cols': 80}),但是您传递的是set带有 2 个元素的 a (您写的是{'cols', 80})。

请注意您如何使用逗号,而不是冒号:

更正后的代码是:

class EntryForm(forms.ModelForm):
    class Meta:
        ...
        widgets = {
            'text': forms.Textarea(attrs={'cols': 80}),
        }

推荐阅读