简体   繁体   中英

How to create a table with links to change boolean values of a model instance in Django?

I have a ListView where I show customer orders in multiple tables. There is one table for orders that are sent (not yet marked as 'received'), one table for 'received' orders, one for 'processed' order and one for 'delivered' orders.

This list is a staff list, only certain users have access to it.

What I would like to do is to add a button (link or maybe a submit button for a form) to each order row.

For example, in the table for the sent orders (not yet 'received') there should be a button that says 'Mark as received' ('Kvittera' in Swedish), in the 'received' table, the button should say 'Mark as processed' ('Klar' in Swedish) and so forth.

This is a picture of how I would like it to look (sorry for the Swedish):

图片外观

The model has three boolean fields; order_received , order_processed and order_delivered . If I were to push the button 'Kvittera' in the table, the boolean value of order_received should change from False to True , and so forth. Note that you should never be able to change it back to False .

I can set up a button/link that GETs a URL, ie http://example.com/orders/1/receive which runs a view that does exactly this and then redirects to the list page again. I have several problems with this though:

  1. You should not change anything with GET (use POST, PUT or PATCH)
  2. You should not use verbs in URLs (receive in this case)

One solution to this problem, I think, is to create a form which POSTs data instead. But in this form there should be no fields, and one form is needed per order row. The form is essentially only a submit button.

As well, every form should be bound to the instance of the order in question and should programmatically only change one value from False to True. How can I accomplish this? Am I overthinking it or completely off track?

I think you are on the right track with your solution to post data through forms, sending data like : {'state': 'received'}. Also, I guess that Django Formsets might be useful for your design: https://docs.djangoproject.com/en/1.9/topics/forms/formsets/ . Change the doc version if you don't use Django 1.9

Another solution would be to have a dropdown/ ChoiceField with id-s of all the objects for which it is possible to change order_received to True. You can make two more dropdowns for order_processed and order_delivered . Then, hide whole the form, and with some JS fiddling make the buttons to update the form values and send the form.

But, being honest, it will just not reuse the built in Django functions, so I would still advice to say what @phiberjenz mentions and make a formset . If you don't want to use JS you could make the buttons next to the orders to work as submit buttons AND send the post that would be processed by your server-side form.

I ended up creating a RedirectView that called a method on the instance changing the state of the order. This is called with a GET request, but super simple and according to https://docs.djangoproject.com/en/1.10/ref/class-based-views/base/ (at the bottom) the example shows exactly this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM