Как кэшировать формы django?
<
У меня есть этот миксин:
class ModelFormMixin:
def post(self, request, *args, **kwargs):
self.object_list = self.get_queryset()
form = self.get_form()
if form.is_valid():
form.save()
queryset_cache_key = f'{self.model.__name__}_queryset'
cache.delete(queryset_cache_key)
return self.form_valid(form)
else:
return self.form_invalid(form)
А эти формы:
from typing import Type
from django import forms
from django.forms import ModelForm
from .models import Book, Author, Genre, OrderItem, Bill
class DynamicModelForm(ModelForm):
class Meta:
model = None
fields = '__all__'
@classmethod
def create(cls, _model: Type):
class Meta(cls.Meta):
model = _model
form_class = type(f"{_model.__name__}Form", (cls,), {'Meta': Meta})
return form_class
class OrderItemForm(DynamicModelForm.create(OrderItem)):
price = forms.DecimalField(
max_digits=5,
decimal_places=2,
label='Ціна', # price
required=False,
disabled=True
)
def clean(self):
cleaned_data = super().clean()
quantity = cleaned_data.get('quantity')
book = cleaned_data.get('book')
if book and quantity:
cleaned_data['price'] = book.price * quantity
else:
cleaned_data['price'] = 0
return cleaned_data
Вот пример моей точки зрения:
class BookView(ModelContextMixin, ModelFormMixin, ModelSuccessUrlMixin, generic.edit.FormMixin, generic.ListView):x
model = Book
template_name = 'base/books.html'
form_class = DynamicModelForm.create(Book)
extra_context = {'add_button_name': 'Додати нову книгу'} # Add new book
А вот мой шаблон:
<div class="section-button">
<button class="add-new-button" onclick="toggleForm()">{{ add_button_name }}</button>
</div>
<h2>{{ model_name|title }}</h2>
<input type="text" placeholder="Пошук книг за назвою, автором або жанром..." id="search-books">
<div class="form-container" id="form-container" style="display: {% if form.errors %} block {% else %} none {% endif %};">
<h3>{{ add_button_name }}</h3>
<form method="post">
{% csrf_token %}
{% for field in form %}
<div class="form-group">
<label for="{{ field.id_for_label }}">{{ field.label }}</label>
{{ field }}
{% if field.errors %}
<div class="error-message">
{% for error in field.errors %}
<p>{{ error }}</p>
{% endfor %}
</div>
{% endif %}
</div>
{% endfor %}
<button type="submit">Додати</button>
</form>
</div>
<script>
function toggleForm() {
const formContainer = document.getElementById("form-container");
formContainer.style.display = formContainer.style.display === "none" ? "block" : "none";
}
</script>
Я пытался сделать что-то вроде этого:
class DynamicModelForm(ModelForm):
class Meta:
model = None
fields = '__all__'
@classmethod
def create(cls, _model: Type):
# Cache key based on model name to ensure a unique form per model
cache_key = f"{_model.__name__}_form_class"
# Check if form class is already cached
form_class = cache.get(cache_key)
if not form_class:
class Meta(cls.Meta):
model = _model
# Dynamically create and cache the form class
form_class = type(f"{_model.__name__}Form", (cls,), {'Meta': Meta})
cache.set(cache_key, form_class, timeout=300) # Cache for 5 minutes
return form_class
Но получил эту ошибку:
_pickle.PicklingError: Can't pickle <class 'django.forms.widgets.OrderItemForm'>: attribute lookup OrderItemForm on django.forms.widgets failed