Django - Вызов функции в ListView или модели для изменения состояния bolean модели
Я хочу вызвать функцию - из модели или из Listview, которая будет изменять состояние Order.isDone - TRUE или FALSE после нажатия на кнопку в шаблоне.
Model.py:
class Order(models.Model):
isDone = models.BooleanField(default=False, verbose_name='Zrealizowane')
views.py:
class OrderListView (ListView):
model = Order
template_name = 'orders/orders_list.html'
ordering = ['-orderDate']
urls.py:
urlpatterns = [
path('', views.home, name='page-home'),
path('orders_list/', OrderListView.as_view(), name='page-orders-list'),
path('completed_orders_list/', OrderCompletedListView.as_view(), name='page-completed-orders-list'),
path('orders/order_create/', OrderCreateView.as_view(), name='page-order-create'),
path('orders/<int:pk>/delete/', OrderDeleteView.as_view(), name='page-order-delete'),
]
template:
<tbody>
{% for order in object_list %}
{% if order.isDone == False %}
<tr>
<td>
<button type="button" class="btn btn-secondary" data-toggle="modal" data-target="#exampleModalCenter">Szczegóły</button>
<form action="{% url 'page-orders-list' order.id %}" method="post">
{% csrf_token %}
<button class="btn btn-info btn-sm">Finish order</button>
<form>
<a class="btn btn-danger adminButton" href="{% url 'page-order-delete' order.id %}">Usuń</a>
</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}
Какой самый простой способ сделать это?
Я предлагаю использовать для этого другое представление. Вы можете использовать метод get в представлении для изменения статуса заказа. В вашем HTML вам нужно будет использовать только ссылку вместо формы.
То есть что-то вроде этого:
views.py
class OrderFinishView(RedirectView):
success_url = None # After finishing the order, where do you want to redirect the user?
def get(self, request, *args, **kwargs):
order_id = self.kwargs['pk_order'] # pk_order must be in your URL
order = get_object_or_404(Order, pk=order_id)
order.is_done = True
order.save()
return super().get(request, *args, **kwargs)
urls.py
urlpatterns = [
path('', views.home, name='page-home'),
path('orders_list/', OrderListView.as_view(), name='page-orders-list'),
path('completed_orders_list/', OrderCompletedListView.as_view(), name='page-completed-orders-list'),
path('orders/order_create/', OrderCreateView.as_view(), name='page-order-create'),
path('orders/<int:pk>/delete/', OrderDeleteView.as_view(), name='page-order-delete'),
path('orders/<int:pk_order>/finish', OrderFinishView.as_view(), name='page-order-finish'),
]
шаблон
<tbody>
{% for order in object_list %}
{% if order.isDone == False %}
<tr>
<td>
<a href={% url 'page-order-finish' order.id %}>Finish</a>
</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}
Другая идея - использовать UpdateView для обновления заказа с помощью PartialOrderForm, которая будет содержать только поле is_done.
Я использую решение @vinkomlacic solutionhave, но изменил функцию get:
def get(self, request, *args, **kwargs):
order_id = self.kwargs['pk_order'] # pk_order must be in your URL
order = get_object_or_404(Order, pk=order_id)
order.isDone = True
order.save()
return redirect(self.success_url)
Похоже, теперь все работает правильно после установки success_url в классе