Home > other >  Django - Calling function in ListView or model to change model bolean status
Django - Calling function in ListView or model to change model bolean status

Time:03-07

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

  • Related