Как получить переменные шаблона с помощью FormView? - PullRequest
0 голосов
/ 13 марта 2020

Я сейчас следую учебнику Mozilla Django (https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Forms). Учебник в основном показывает, как создавать формы с использованием функций. Я пытаюсь заставить работать тот же вид функции, используя общий вид класса c (FormView). Я могу заставить работать большую часть кода, кроме двух вещей. Во-первых, я не могу сохранить дату исполнения. И, во-вторых, я не знаю, как получить доступ к полям модели в моем шаблоне, используя переменные шаблона.

Вот моя модель формы из файла forms.py.

class RenewBookModelForm(ModelForm):
    def clean_due_back(self):
        data = self.cleaned_data['due_back']

        # Check if a date is not in the past.
        if data < datetime.date.today():
            raise ValidationError(ugettext_lazy(
                'Invalid date - renewal in past'))

        # Check if a date is in the allowed range (+4 weeks from today).
        if data > datetime.date.today() + datetime.timedelta(weeks=4):
            raise ValidationError(ugettext_lazy(
                'Invalid date - renewal more than 4 weeks ahead'))

        # Remember to always return the cleaned data.
        return data

    class Meta:
        model = BookInstance
        fields = ['due_back']
        labels = {'due_back': ugettext_lazy('New renewal date')}
        help_texts = {'due_back': ugettext_lazy(
            'Enter a date between now and 4 weeks (default 3).')}

Модель формы, реализованная как функция:

@permission_required('catalog.can_mark_returned')
def renew_book_lirarian(request, pk):
    book_instance = get_object_or_404(BookInstance, pk=pk)

    # If this is a POST request then process the Form data
    if request.method == 'POST':

        # Create a form instance and populate it with data from the request (binding):
        form = RenewBookModelForm(request.POST)

        # Chech if the form is valid
        if form.is_valid():
            # process that data in form.cleaned_data as required (here we just write to the model due_back field)
            book_instance.due_back = form.cleaned_data['due_back']
            book_instance.save()

            # redirect to a new URL
            return HttpResponseRedirect(reverse('all-borrowed'))

    # If this is a GET (or any other method) create the default form.
    else:
        proposed_renewal_date = datetime.date.today() + datetime.timedelta(weeks=3)
        form = RenewBookModelForm(initial={'due_back': proposed_renewal_date})

    context = {
        'form': form,
        'book_instance': book_instance
    }

    return render(request, 'catalog/book_renew_librarian.html', context=context)

Это мое представление на основе классов из моего файла views.py:

class RenewBookLibrarian(LoginRequiredMixin, PermissionRequiredMixin, generic.FormView):
    """Generic class-based view for forms."""
    template_name = 'catalog/book_renew_librarian.html'
    permission_required = 'catalog.can_mark_returned'
    form_class = RenewBookModelForm
    success_url = reverse_lazy('all-borrowed')

    def get_initial(self):
        proposed_renewal_date = datetime.date.today() + datetime.timedelta(weeks=3)
        initial = {'due_back': proposed_renewal_date}

        return initial

И, наконец, это мой файл шаблона, в котором Я получу sh для доступа к полям модели:

{% extends 'base_generic.html' %}

{% block content %}
<h1>Renew: {{ book_instance.book.title }}</h1>
<p>Borrower: {{ book_instance.borrower }}</p>
<p {% if book_instance.is_overdue %} class="text-danger" {% endif %}>Due date: {{ book_instance.due_back }}</p>

<form action="" method="POST">
    {% csrf_token %}
    <table>
        {{ form.as_table }}
    </table>
    <input type="submit" value="submit">
</form>
{% endblock %}

Переменная book_instance в шаблоне не работает, поэтому я хотел бы знать, как я могу отображать поля из моего BookInstance модель.

1 Ответ

0 голосов
/ 13 марта 2020

Чтобы добавить book_instance в контекст шаблона, вы можете переопределить get_context_data.

. В FormView вместо проверки if form.is_valid() вы переопределяете form_valid метод (см. Документацию по видам для базисных c форм ).

class RenewBookLibrarian(LoginRequiredMixin, PermissionRequiredMixin, generic.FormView):
   ...

   def get_context_data(self, **kwargs):
       context = super().get_context_data(**kwargs)
       context['book_instance'] = get_object_or_404(BookInstance, pk=self.kwargs['pk'])

   def form_valid(self, form):
       book_instance = get_object_or_404(BookInstance, pk=self.kwargs['pk'])
       book_instance.due_date = form.cleaned_data['due_date']
       book_instance.save()
       return super().form_valid(form) # will redirect to the success url
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...