Я сейчас следую учебнику 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 модель.