I have a class-based view (IndexView at views.py) that shows a table with all the data stored in the database.
This view is rendered in index.html using a def get_queryset(self)
to obtain all the data. No issues yet.
The difficult part for me is trying to do it using a form, to be able to modify and save the amount column. I have no issues with the POST part, where I use AJAX to save the new values. Where I'm having issues is getting the initial values from the database to populate a Django Form (forms.py)
I tried using initial
argument in the definition of the form fields (at forms.py), even overriding __init__
at the form definition, but I don't know how to get "one value". I mean, the closer I've been in my tests was populating a MultipleChoiceField with:
forms.ModelMultipleChoiceField(queryset=Item.objects.order_by('code__name'))
(achieving a multiple choice field of Item object (1), Item object (2), etc.
)
But how do you populate a single IntegerField or CharField with the content of the database to show a form-based table field in the template?
I'm trying first with a single item (to try to understand how to reference one item/value to populate them using the database) before doing it with the whole table:
index.hml:
...
<form class='my-ajax-form' method='POST' action='.' data-url='{{ request.build_absolute_uri|safe }}'>
{% csrf_token %}
{{form.as_table|safe}}
<button type='submit'>Save changes</button>
</form>
...
models.py:
class Code(models.Model):
name = models.CharField(max_length=6)
description = models.CharField(max_length=100)
def __str__(self):
return self.name
class Item(models.Model):
code = models.ForeignKey(Code, on_delete=models.DO_NOTHING)
amount = models.IntegerField(default=0)
forms.py:
class ItemForm(forms.Form):
code = forms.CharField(max_length=6)
description = forms.CharField(max_length=100)
amount = forms.IntegerField()
views.py:
class IndexView(generic.ListView, AjaxFormMixin, FormView):
template_name = 'inventory/index.html'
context_object_name = 'items_list'
form_class = ItemForm
def form_invalid(self, form):
...
def form_valid(self, form):
...
def get_queryset(self):
...
I checked these docs & some similar old issues, but I tried some of the suggestions/examples with no success:
- https://docs.djangoproject.com/en/2.0/topics/forms/modelforms/#a-full-example
- https://www.webforefront.com/django/formprocessing.html
- Pre-populating Django Forms
- Populate a django form with data from database in view
I'm using Django 2.0.2
Any help would be appreciated. Thanks in advance.
EDIT: Trying to do something using UpdateView as andi suggests. Added (trying to get one value by id):
class ItemUpdate(UpdateView):
form_class = JoinForm
def get_object(self,queryset=None):
obj = Item.objects.get(id=self.kwargs['2'])
return obj
And pointed url to path('', views.ItemUpdate.as_view(), name='index')
but always get KeyError: '2'
what about using generic
from django.views.generic.edit import UpdateView
straight on model?https://docs.djangoproject.com/en/2.0/ref/class-based-views/generic-editing/#updateview
views.py:
urls.py
/templates/demo/item_form.html
If something regarding settings or config is unclear please refer to the repo with demo: https://github.com/andilabs/cbv
UPDATE
added modelformset producing what you need in ListView
this just displays data in forms, you have take care of rest.
One thing you can do is iterate through the item list, and set the value attribute of the input tag of each field to form.field_name.value
There are multiple ways of loading data into forms, as far as I know:
You are using
FormView
CBV which has a func calledget_intial
:You can override the init func: