Reputation: 523
I have a CBV that use ListView
at first here my views.py
class InventoryListView(ListView):
context_object_name = 'inventorys'
model = models.Inventory
and here my template_list.html
{% for inventory in inventorys %}
<tr>
<td>{{ inventory.name }}</td>
<td>{{ inventory.sn }}</td>
<td>{{ inventory.employee.name }}</td>
<td>{{ inventory.desc }}</td>
</tr>
{% endfor %}
it returns all the data as expected.
but I need add form with it. and then add some of code to my views.py
class InventoryListView(ListView):
template_name ='system/inventory_list.html'
context_object_name = 'inventorys'
model = models.Inventory
def get(self, request):
form = InventoryForm()
return render(request, self.template_name, {'form': form})
def post(self, request):
form = InventoryForm(request.POST)
and here my forms.py
class InventoryForm(forms.ModelForm):
name = forms.CharField(max_length=255)
sn = forms.DecimalField(max_digits=20, decimal_places=0)
desc = forms.CharField(widget=forms.Textarea)
employee = forms.ModelChoiceField(queryset=Employee.objects.all(), to_field_name="id")
class Meta:
model = Inventory
fields = ('name', 'sn', 'desc', 'employee')
and here my template_list.html
{% for inventory in inventorys %}
<tr>
<td>{{ inventory.name }}</td>
<td>{{ inventory.sn }}</td>
<td>{{ inventory.employee.name }}</td>
<td>{{ inventory.desc }}</td>
</tr>
{% endfor %}
<form method="post" action="{% url 'system:inventory_create' %}">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit">
</form>
now form working perfectly and checked on my DB its submitted. but list of data not showing like before, because I add:
def get(self, request):
form = InventoryForm()
return render(request, self.template_name, {'form': form})
to my views.py
so how to make both works, list of data & form.
Upvotes: 7
Views: 12377
Reputation: 31
To save the state of the form
def get_context_data(self, **kwargs):
context = super(RecentChannels, self).get_context_data(**kwargs)
context['form'] = RecentChannelsForm(self.request.GET)
return context
Upvotes: 1
Reputation: 308949
Try to avoid overriding get
or post
for generic class-based-views. It's easy to end up duplicating existing functionality or having to repeat code.
In this case, you can add the form to the template context by overriding the get_context_data
method.
class InventoryListView(ListView):
template_name ='system/inventory_list.html'
context_object_name = 'inventorys'
model = models.Inventory
def get_context_data(self, **kwargs):
context = super(InventoryListView, self).get_context_data(**kwargs)
context['form'] = InventoryForm()
return context
...
Upvotes: 17
Reputation: 2966
I have a similar situation. I tried many things, and now using ListView
with FormMixin
.
First, I make FormListView
inheriting ListView
and FormMixin
. Here's my code
from django.http import Http404
from django.views.generic import ListView
from django.views.generic.edit import FormMixin
from django.utils.translation import ugettext as _
class FormListView(FormMixin, ListView):
def get(self, request, *args, **kwargs):
# From FormMixin
form_class = self.get_form_class()
self.form = self.get_form(form_class)
# From ListView
self.object_list = self.get_queryset()
allow_empty = self.get_allow_empty()
if not allow_empty and len(self.object_list) == 0:
raise Http404(_(u"Empty list and '%(class_name)s.allow_empty' is False.")
% {'class_name': self.__class__.__name__})
context = self.get_context_data(object_list=self.object_list, form=self.form)
return self.render_to_response(context)
def post(self, request, *args, **kwargs):
return self.get(request, *args, **kwargs)
As you see, I made my own get
for FormMixin and
ListView` both.
And inheriting this, I make my own SomeFormListView
, In your case InventoryFormListView
.
class InventoryFormListView(FormListView):
template_name ='system/inventory_list.html'
context_object_name = 'inventorys'
model = models.Inventory
# FormListView
form_class = YourCustomModelForm
# your custom method
Upvotes: 1
Reputation: 8525
Send the form through get_context_data()
method:
def get_context_data(self, **kwargs):
context = super(InventoryListView,self).get_context_data(**kwargs)
context['form'] = InventoryForm()
return context
Upvotes: 2