Разница между args=[topic.id] и args=[topic_id] при использовании возврата HttpResponseRedirect(reverse) в Django

Я следую руководству по созданию простого приложения для блога с помощью Django.

Я заметил, что в представлении new_entry() нам нужно передать topic_id в agrs при использовании обратной функции:

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, default='Добавить заголовок')

модели.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

формы.ру:

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})}

После внесения этих изменений я получил следующую ошибку, когда попытался отредактировать заголовок записи по умолчанию:

NameError at /edit_entry/4/ глобальное имя 'topic_id' не определено

Я изменил args=[topic_id] на args=[topic.id] в представлении edit_entry() файла views.py, и теперь он работает нормально, есть идеи, почему это так? Какая разница между topic_id и theme.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 %}

Спасибо заранее за любые советы


person luisgc93    schedule 27.02.2018    source источник


Ответы (1)


В вашем первом представлении у вас есть topic_id из URL-адреса, и вы извлекаете topic из базы данных в первой строке, поэтому вы можете использовать topic_id или topic в представлении.

def 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 из URL-адреса и получаете topic через запись. Вы нигде не устанавливаете topic_id, поэтому вы должны использовать topic.

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