在Django中使用返回HttpResponseRedirect(反向)时,args = [topic.id]和args = [topic_id]之间的区别

时间:2018-02-27 20:05:10

标签: django reverse args

我正在按照教程从Django构建一个简单的博客应用程序。

我注意到在new_entry()视图中,我们需要在使用反向函数时在agrs中传递 topic_id

def new_entry(request, topic_id):
"""Add a new entry for a particular 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)

但是,在创建edit_entry()视图(允许用户编辑现有条目)时,我们需要传递 topic.id

def edit_entry(request, entry_id):
"""Edit an existing entry"""
entry = Entry.objects.get(id=entry_id)
topic = entry.topic

if request.method != 'POST':
    #Initial request, render the form with current entry
    form = EntryForm(instance=entry)
else:
    #Submit changes, process data
    form = EntryForm(instance=entry, data=request.POST)
if form.is_valid():
    form.save()
    return HttpResponseRedirect(reverse('learning_logs:topic', args=[topic.id]))
context = {'topic':topic, 'entry':entry, 'form':form}
return render(request,'learning_logs/edit_entry.html', context)

最初我认为这是一个错误所以我在两个反向函数中都使用了args = [topic_id]并且工作正常

后来,我决定要为每个条目添加一个标题,因此我对models.py进行了一些小的更改,将这些更改迁移到数据库,然后将模板更改为包含{{entry.title}}。

基本上,我所做的只是将此代码添加到models.py

title = models.CharField(max_length = 200,默认='添加标题')

models.py:

class Topic(models.Model):
"""A topic the user is learning about"""
text = models.CharField(max_length = 200)
date_added = models.DateTimeField(auto_now_add = True)
def __str__(self):
    """Return a string representation of the model"""
    return self.text

class Entry(models.Model):
    """A blog post about a particular topic"""
    topic = models.ForeignKey(Topic)
    title = models.CharField(max_length=200, default='Add a title')
    text = models.TextField()
    date_added = models.DateTimeField(auto_now_add = True)

    class Meta:
        verbose_name_plural = 'entries'

    def __str__(self):
        """Return a string representation of the model"""
        char_numb = len(self.text)
        if char_numb > 50:
            return self.text[:50] + "..."
        else:
            return self.text

forms.py:

from django import forms
from .models import Topic, Entry


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

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

添加这些更改后,当我尝试编辑条目的默认标题时出现以下错误:

/ edit_entry / 4 /的NameError 全局名称'topic_id'未定义

我在views.py文件edit_entry()视图中将args = [topic_id]更改为args = [topic.id],现在它工作正常,任何想法为什么会这样? 在此上下文中topic_id和topic.id之间有什么区别?

这是edit_entry.html模板,以防它有任何区别:

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

{% block content %}
<h1><a href = "{% url 'learning_logs:topic' topic.id %}">{{topic}}</a>
</h1>

<p>Edit your entry</p>

<form action = "{% url 'learning_logs:edit_entry' entry.id %}" method 
= 'post'>

        {% csrf_token %}
        {{ form.as_p }}

    <button name = "submit">save changes</button>

</form>


{% endblock content %}

提前感谢任何建议

1 个答案:

答案 0 :(得分:0)

在您的第一个视图中,您从网址获得了topic,并且您从第一行的数据库中获取了topic_id,因此您可以使用topicdef new_entry(request, topic_id): """Add a new entry for a particular topic""" topic = Topic.objects.get(id=topic_id) 在视图中。

topic

在他们查看的模板上下文中,您设置topic_id但不设置topic.id。因此,您只能在模板中使用context = {'topic': topic, 'form': form}

entry_id

在第二个视图中,您会从网址获取topic并通过该条目获得topic_id。您没有在任何地方设置topic,因此您必须使用def edit_entry(request, entry_id): """Edit an existing entry""" entry = Entry.objects.get(id=entry_id) topic = entry.topic

Meta