Книга «Изучаем Python»


Рис. 19.1. Страница для добавления новой темы Редактирование данных    413



Pdf көрінісі
бет227/238
Дата07.01.2022
өлшемі7,86 Mb.
#18670
түріКнига
1   ...   223   224   225   226   227   228   229   230   ...   238
Байланысты:
2 5343781172763690906

Рис. 19.1. Страница для добавления новой темы


Редактирование данных    413

Добавление новых записей

Теперь, когда пользователь может добавлять новые темы, он также захочет добав-

лять новые записи. Мы снова определим URL, напишем новую функцию и шаблон 

и создадим ссылку на страницу. Но сначала нужно добавить в 

forms .py

 еще один 

класс.


Класс EntryForm

Мы должны создать форму, связанную с моделью 

Entry

, но более специализиро-



ванную по сравнению с 

TopicForm

:

forms.py

from django import forms

from .models import Topic, Entry

class TopicForm(forms.ModelForm):

...

class EntryForm(forms.ModelForm):



    class Meta:

        model = Entry

        fields = ['text']

        labels = {'text': ''}



        widgets = {'text': forms.Textarea(attrs={'cols': 80})}

Сначала в команду 

import


 к 

Topic


 добавляется 

Entry


. Новый класс 

EntryForm

 на-

следует от 



forms.ModelForm

 и содержит вложенный класс 

Meta

 с указанием модели, 



на которой он базируется, и поле, включаемое в форму. Полю 

'text'


 снова назна-

чается пустая надпись .

В точке  включается атрибут 

widgets


Виджет (widget) представляет собой эле-

мент формы HTML: однострочное или многострочное текстовое поле, раскрываю-

щийся список и т. д. Включая атрибут 

widgets


, вы можете переопределить виджеты, 

выбранные Django по умолчанию. Приказывая Django использовать элемент 

forms.

Textarea


, мы настраиваем виджет ввода для поля 

'text'


, чтобы ширина текстовой 

области составляла 80 столбцов вместо значения по умолчанию 40. У пользователя 

будет достаточно места для создания содержательных записей.

URL-адрес для new_entry

Необходимо включить аргумент 

topic_id


 в URL-адрес для создания новой записи, 

потому что запись должна ассоциироваться с конкретной темой. Вот как выглядит 

URL, который мы добавляем в 

learning_logs/urls .py

:

urls.py

...


urlpatterns = [

...


    # Страница для добавления новой записи

    url(r'^new_entry/(?P\d+)/$', views.new_entry, name='new_entry'),

]



414    Глава 19  •  Учетные записи пользователей

Эта  схема  URL  соответствует  любому  URL-адресу  в  форме  http://



localhost:8000/new_entry/id/, где id — число, равное идентификатору темы. 

Выражение 

(?P\d+)

 захватывает числовое значение и сохраняет 

его в переменной 

topic_id


. При запросе URL-адреса, соответствующего этой 

схеме, Django передает запрос и идентификатор темы функции представления 

new_entry()

.

Функция представления new_entry()



Функция представления 

new_entry

 очень похожа на функцию добавления новой 

темы:


views.py

from django.shortcuts import render

...

from .models import Topic



from .forms import TopicForm, EntryForm

...


def new_entry(request, topic_id):

    """Добавляет новую запись по конкретной теме."""

    topic = Topic.objects.get(id=topic_id)



    

    if request.method != 'POST':



        # Данные не отправлялись; создается пустая форма.

        form = EntryForm()        



    else:

        # Отправлены данные POST; обработать данные.

        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)

Мы обновляем команду 

import


 и включаем в нее только что созданный класс 

EntryForm

. Определение 

new_entry()

 содержит параметр 

topic_id


 для сохранения 

полученного значения из URL. Идентификатор темы понадобится для отображе-

ния страницы и обработки данных формы, поэтому мы используем 

topic_id


 для 

получения правильного объекта темы .

В точке  проверяется метод запроса: POST или GET. Блок 

if

 выполняется для 



запроса GET, и мы создаем пустой экземпляр 

EntryForm

 . Для метода запроса 

POST мы обрабатываем данные, создавая экземпляр 

EntryForm

, заполненный 

данными POST из объекта запроса . Затем проверяется корректность данных 

формы. Если данные корректны, необходимо задать атрибут 

topic

 объекта записи 



перед сохранением его в базе данных.


Редактирование данных    415

При вызове 

save()

 мы включаем аргумент 



commit=False

  для того, чтобы создать 

новый объект записи и сохранить его в 

new_entry

, не сохраняя пока в базе данных. 

Мы присваиваем атрибуту 

topic

 объекта 



new_entry

 тему, прочитанную из базы дан-

ных в начале функции 

, после чего вызываем 



save()

 без аргументов. В результате 

запись сохраняется в базе данных с правильной ассоциированной темой.

В  точке 

  пользователь  перенаправляется  на  страницу  темы.  При  вызове 



reverse()

 должны передаваться два аргумента: имя схемы URL, для которой 

генерируется URL-адрес, и список аргументов со всеми аргументами, которые 

должны быть включены в URL. Список аргументов содержит всего один элемент 

topic_id

. Вызов 


HttpResponseRedirect()

 перенаправляет пользователя на стра-

ницу темы, для которой была создана запись, и пользователь видит новую запись 

в списке записей.

Шаблон new_entry

Как видно из следующего кода, шаблон 

new_entry

 похож на шаблон 

new_topic

:

new_entry.html

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

{% block content %}

 
{{ topic }}


    


 
Add a new entry:

 



    {% csrf_token %}

    {{ form.as_p }}

   

 

    

{% endblock content %}



В начале страницы выводится тема , чтобы пользователь мог видеть, в какую тему 

добавляется новая запись. Тема также служат ссылкой для возврата к основной 

странице этой темы.

Аргумент 

action

 формы включает значение 



topic_id

 из URL, чтобы функция 

 представления могла связать новую запись с правильной темой . В остальном 

этот шаблон почти не отличается от 

new_topic .html

.

Создание ссылки на страницу new_entry



Затем необходимо создать ссылку на страницу 

new_entry

 на каждой странице темы:

topic.html

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

{% block content %}

Topic: {{ topic }}





416    Глава 19  •  Учетные записи пользователей

Entries:

 

    add new entry

 


    ...


{% endblock content %}

Ссылка добавляется перед выводом записей, потому что добавление новой запи-

си является самым частым действием на этой странице. На рис. 19.2 изображена 

страница 

new_entry

. Теперь пользователь может добавить сколько угодно новых 

тем и новых записей по каждой теме. Опробуйте страницу 

new_entry

, добавив не-

сколько записей для каждой из созданных вами тем.



Достарыңызбен бөлісу:
1   ...   223   224   225   226   227   228   229   230   ...   238




©emirsaba.org 2024
әкімшілігінің қараңыз

    Басты бет