Ошибка формы Django 'this field is required' на нередактируемом поле
Я пытаюсь создать форму, которая позволит мне классифицировать/редактировать мои банковские транзакции. В идеале все некатегоризированные транзакции будут отображаться на одной странице (в наборе форм), и я смогу редактировать некоторые/все из них. Когда я нажимаю кнопку "отправить" на наборе форм, я хочу сохранить все изменения и перейти на страницу подтверждения.
Вот моя модель для транзакции:
class Transaction(models.Model):
description = models.CharField(max_length=200)
post_date = models.DateTimeField('date')
account = models.ForeignKey(Account, null=True, on_delete=models.SET_NULL)
category = models.ForeignKey(Category, null=True, on_delete=models.SET_NULL)
amount = models.DecimalField(max_digits=9, decimal_places=2)
uuid = models.CharField(
max_length=200,
primary_key = True,
unique = True, editable=False)
def __str__(self):
return self.description
Дата, описание и сумма важны для отображения в форме, поскольку они помогают мне понять, как классифицировать транзакцию. Я не хочу случайно отредактировать дату или сумму, поэтому я сделал их доступными для чтения в форме. У транзакций также есть поля uuid и account, но они не имеют отношения к категоризации, и я не хочу их редактировать, поэтому их вообще не следует показывать.
Моя форма и набор форм выглядят следующим образом:
class TransactionForm(ModelForm):
class Meta:
model = Transaction
exclude = ('uuid', 'account')
def __init__(self, *args, **kwargs):
super(TransactionForm, self).__init__(*args, **kwargs)
cat = self.fields['category']
cat.required = False
cat.blank = True
self.fields['description']
self.fields['amount'].readonly = True
self.fields['post_date'].readonly = True
TransactionFormset = modelformset_factory(Transaction, form=TransactionForm)
Если я пытаюсь отредактировать некоторые транзакции и отправить этот набор форм, я получаю ошибку на каждой форме, которая говорит "uuid - Это поле обязательно". Мне трудно понять, почему uuid имеет значение для формы, если я (a) явно исключил его в конструкции формы и (b) сделал поле редактируемым=False на уровне модели
Представление, которое я использую для вывода набора форм, следующее:
class TransactionFormView(LoginRequiredMixin, generic.list.ListView):
login_url = 'accounts/login'
redirect_field_name = 'redirect_to'
template_name = 'transactions_form.html'
model = Transaction
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
formset = TransactionFormset()
context['formset'] = formset
context['saved'] = False
return context
def post(self, request):
formset = TransactionFormset(request.POST)
foundValid = False
for i, form in enumerate(formset):
if (form.is_valid() and form.initial):
form_info = form.save(commit=False)
xact = Transaction.objects.filter(uuid=form.initial['uuid']).first()
if xact:
xact.category = form_info.category
xact.description = form_info.description
xact.save()
foundValid = True
else:
logger.info(form.errors)
if foundValid:
messages.success(request, "Transactions processed! Thanks for sorting :)")
return render(request, "transactions_form.html", {"formset" : formset , "saved": foundValid })
и, наконец, шаблон, над которым работает представление:
{% block content %}
{% if saved %}
<h1>Thanks!</h1>
Your transactions have been categorised.
<a href="{% url 'fill' %}">[Want to do more?]</a>
{% else %}
<table>
<tr>
<th>Date</th>
<th>Description</th>
<th>Amount</th>
<th>Category</th>
</tr>
<form method="post">
{{ formset.management_form }}
{% csrf_token %}
{% for form in formset %}
<tr>
{{ form.errors }}
</tr>
<tr>
<td>{{ form.post_date }}</td>
<td>{{ form.description }}</td>
<td>{{ form.amount }}</td>
<td>{{ form.category }}</td>
</tr>
{% endfor %}
</table>
<input type="submit" value="Submit">
</form>
{% endif %}
{% endblock %}