Django ListView с формой - PullRequest
0 голосов
/ 10 мая 2018

У меня есть CBV, который сначала использует ListView мой views.py

class InventoryListView(ListView):
    context_object_name = 'inventorys'
    model = models.Inventory

а вот мой 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 %}

возвращает все данные, как ожидалось.

но мне нужно добавить форму с ним. а затем добавить часть кода в мой 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)

а вот мой 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')

а вот мой 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>

теперь форма работает отлично и проверила на моей БД свою отправленную. но список данных не отображается как раньше, потому что я добавляю:

    def get(self, request):
        form = InventoryForm()
        return render(request, self.template_name, {'form': form})

на мой views.py

как сделать так, чтобы оба работали, список данных и форма.

Ответы [ 3 ]

0 голосов
/ 10 мая 2018

Отправьте форму через get_context_data() метод:

def get_context_data(self, **kwargs):
     context =  super(InventoryListView,self).get_context_data(**kwargs)
     context['form'] = InventoryForm()
     return context
0 голосов
/ 10 мая 2018

У меня похожая ситуация. Я перепробовал много вещей, и теперь использую ListView с FormMixin.

Сначала я создаю FormListView, наследуя ListView и FormMixin. Вот мой код

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)

Как видите, я сделал свой собственный get для FormMixin and ListView` для обоих.

И, унаследовав это, я создаю свой собственный SomeFormListView, В вашем случае InventoryFormListView.

class InventoryFormListView(FormListView):
    template_name ='system/inventory_list.html'
    context_object_name = 'inventorys'
    model = models.Inventory

    # FormListView
    form_class = YourCustomModelForm

    # your custom method 
0 голосов
/ 10 мая 2018

Старайтесь избегать переопределения get или post для общих представлений на основе классов.В конечном итоге легко дублировать существующие функции или повторять код.

В этом случае вы можете добавить форму в контекст шаблона, переопределив метод get_context_data.

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

    ...
...