Modelformset обновление нескольких экземпляров модели
Я пытаюсь обновить несколько экземпляров модели, используя modelformset_factory
, чтобы отобразить указанные экземпляры в одной форме, но это не работает.
views.py:
def approve(request,pk):
user = User.objects.get(id=pk)
requests = PendingRequest.objects.filter(member=user)
RequestFormset = modelformset_factory(PendingRequest, form=Approve ,extra=0)
if request.method == "POST":
formset = RequestFormset(request.POST, queryset=requests)
if formset.is_valid():
for form in formset:
form.save()
else:
formset = RequestFormset(queryset=requests)
return render(request, "books/approve.html",{"formset":formset, "users":requests})
forms.py:
class Approve(forms.ModelForm):
class Meta:
model = PendingRequest
exclude = ["member", "book_request", "not_approved"]
models.py:
class PendingRequest(models.Model):
book_request = models.ForeignKey(BorrowBook, on_delete=models.CASCADE, null=True)
member = models.ForeignKey(User, on_delete=models.CASCADE, default="", null=True)
book = models.ForeignKey(Books, on_delete=models.CASCADE, default="", null=True)
approved = models.BooleanField(default=False)
not_approved = models.BooleanField(default=False)
approval_date = models.DateTimeField(auto_now=True, null=True)
шаблон
<body>
<form method="post" action="{% url 'approve' pk=users.0.member.id %}">
{% csrf_token %}
{% for form in formset.management_form %}
{{form}}
{% endfor %}
<table>
<thead>
<tr>
<th>Book Title</th>
<th>Approved</th>
<th>Not Approved</th>
</tr>
</thead>
<tbody>
{% for form in formset %}
<tr>
<td>{{ form.book }}</td>
<td>{{ form.approved }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<button type="submit">Update</button>
</form>
</body>
Когда я нажимаю на кнопку submit в моем шаблоне, он не отправляет никаких данных в базу данных. Есть идеи, как это исправить.
Я также хочу иметь возможность установить поле
.not_approved
в true, если пользователь не нажмет на флажокapproved
в шаблоне. Любая идея о том, как это сделать, будет оценена по достоинству
Вы должны использовать commit=False
для временного сохранения экземпляра, а также использовать save_m2m()
и установить поле not_approved
в True
если пользователь не нажимает на флажок одобрено, вы можете проверить очищенные данные формы на значение одобрено.
Попробуйте следующий вид:
from django.shortcuts import get_object_or_404
def approve(request,pk):
user = get_object_or_404(User, id=pk)
requests = PendingRequest.objects.filter(member=user)
RequestFormset = modelformset_factory(PendingRequest, form=Approve ,extra=0)
if request.method == "POST":
formset = RequestFormset(request.POST, queryset=requests)
if formset.is_valid():
for form in formset:
obj = form.save(commit=False)
if not form.cleaned_data.get('approved'):
obj.not_approved = True
obj.save()
formset.save_m2m()
else:
formset = RequestFormset(queryset=requests)
return render(request, "books/approve.html",{"formset":formset, "users":requests})
Примечание: Лучше использовать
get_object_or_404()
вместоget()
, так как он вызываетget()
на данном менеджере модели, но поднимаетHttp404
вместоDoesNotExist
исключения модели.