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


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



Pdf көрінісі
бет227/238
Дата07.01.2022
өлшемі7,86 Mb.
#18670
түріКнига
1   ...   223   224   225   226   227   228   229   230   ...   238
Рис. 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
әкімшілігінің қараңыз

    Басты бет