使用Django从数据库预填充HTML表单表

时间:2018-03-07 17:41:20

标签: python django database forms populate

我有一个基于类的视图( IndexView views.py ),它显示了一个包含数据库中存储的所有数据的表。 使用def get_queryset(self) index.html 中呈现此视图以获取所有数据。还没有问题。

对我来说,困难的部分是尝试使用表单,以便能够修改和保存金额列。 我对POST部分没有任何问题,我使用AJAX来保存新值。 我遇到问题的地方是从数据库获取初始值以填充Django表单( forms.py

我尝试在表单字段的定义中使用initial参数(在 forms.py ),甚至覆盖表单定义中的__init__但是我不知道如何获得一个价值" 。我的意思是,我在测试中越接近填充 MultipleChoiceField forms.ModelMultipleChoiceField(queryset=Item.objects.order_by('code__name')) (实现Item object (1), Item object (2), etc.)的多选字段

但是,如何使用数据库的内容填充单个 IntegerField CharField 以在模板中显示基于表单的表字段?

我首先尝试使用单个项目(尝试了解如何使用数据库引用一个项目/值来填充它们),然后再对整个表格进行操作:

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):
        ...

我检查了这些文档&amp;一些类似的旧问题,但我尝试了一些建议/例子没有成功:

我正在使用Django 2.0.2

任何帮助将不胜感激。 提前谢谢。

编辑: 尝试使用UpdateView做一些事情,因为andi建议。添加(尝试按ID获取一个值):

class ItemUpdate(UpdateView):
    form_class = JoinForm

    def get_object(self,queryset=None):
        obj = Item.objects.get(id=self.kwargs['2'])
        return obj

并将网址指向path('', views.ItemUpdate.as_view(), name='index')但始终获得KeyError: '2'

3 个答案:

答案 0 :(得分:1)

如何在模型上直接使用通用// here both variables are pointing at the same object Date var1 = new Date(); Date var2 = var1; // this change is done to one object, referenced by both variables var1.setTime(180128); // Since both point at the same object, the output is exactly the same System.out.println(var1); System.out.println(var2); // now we point var2 at a different object, the same one as var3 Date var3 = new Date(); var2 = var3; // Var1 will still be the same as before. But var2 will match var3 System.out.println(var1); System.out.println(var2); System.out.println(var3);

https://docs.djangoproject.com/en/2.0/ref/class-based-views/generic-editing/#updateview

views.py:

from django.views.generic.edit import UpdateView

urls.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})

/templates/demo/item_form.html

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')
]

如果有关设置或配置的内容不清楚,请参阅repo with demo:https://github.com/andilabs/cbv

更新

添加了在ListView中生成所需内容的modelformset

<form action="" method="post">{% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="Update" />
</form>

这只是以表格形式显示数据,你需要休息。

答案 1 :(得分:0)

据我所知,有多种方法可以将数据加载到表单中:

  • 在views.py

您正在使用FormView CBV,其中有一个名为get_intial的函数:

    def get_initial(self):
        initial = super().get_initial()
        initial['<form-field>'] = <initial-value>
        return initial
  • 在forms.py

您可以覆盖 init func:

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['<form-field>'].initial = <initial-value>

答案 2 :(得分:0)

您可以做的一件事是遍历项目列表,并将每个字段的输入标记的value属性设置为form.field_name.value