I want to call a function - from a model or from a Listview that will change Order.isDone status - TRUE or FALSE after clicking the button in template.
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" data-toggle="modal" data-target="#exampleModalCenter">Szczegóły</button>
<form action="{% url 'page-orders-list' order.id %}" method="post">
{% csrf_token %}
<button >Finish order</button>
<form>
<a href="{% url 'page-order-delete' order.id %}">Usuń</a>
</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}
What is the easiest way to do this ?
CodePudding user response:
I suggest using another view for this. You can use the get
method in the view to change the status of the order. The in your HTML you would only need to use a link instead of a form.
So something like this:
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'),
]
template
<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 %}
Another idea is to use an UpdateView to update your order with a PartialOrderForm which would only contain the is_done
field.
CodePudding user response:
I use @vinkomlacic solutionhave but changed the get function:
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)
Seems to be working properly now after setting success_url in class