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<
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:
from django.forms import ModelForm, CharField, Textarea
from django.urls import reverse_lazy
from django.views.generic import UpdateView
from demo.models import Item
class ItemForm(ModelForm):
description = CharField(widget=Textarea)
class Meta:
model = Item
fields = ['code', 'amount']
def save(self, commit=True):
item = super(ItemForm, self).save(commit=commit)
item.code.description = self.cleaned_data['description']
item.code.save()
def get_initial_for_field(self, field, field_name):
if field_name == 'description':
return self.instance.code.description
else:
return super(ItemForm, self).get_initial_for_field(field, field_name)
class ItemUpdateView(UpdateView):
form_class = ItemForm
model = Item
def get_success_url(self):
return reverse_lazy('item-detail', kwargs={'pk': 1})
urls.py
from django.conf.urls import url
from django.contrib import admin
from django.urls import path
from demo.views import ItemUpdateView
urlpatterns = [
url(r'^admin/', admin.site.urls),
path(r'items/<int:pk>/', ItemUpdateView.as_view(), name='item-detail')
]
/templates/demo/item_form.html
<form action="" method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Update" />
</form>
If something regarding settings or config is unclear please refer to the repo with demo: https://github.com/andilabs/cbv
added modelformset producing what you need in ListView
from django.forms import modelformset_factory
class ItemListView(ListView):
model = Item
def get_context_data(self, **kwargs):
data = super(ItemListView, self).get_context_data()
formset = modelformset_factory(Item, form=ItemForm)()
data['formset'] = formset
return data
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 called get_intial
:
def get_initial(self):
initial = super().get_initial()
initial['<form-field>'] = <initial-value>
return initial
You can override the init func:
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['<form-field>'].initial = <initial-value>