【问题标题】:How to pass initial data from QuerySet to formset?如何将初始数据从 QuerySet 传递到 formset?
【发布时间】:2020-04-19 04:51:51
【问题描述】:

我正在开发一个物业管理系统,现在我正在开发一个名为 Property check 的应用程序,它基本上可以保存有关对某些物业进行检查的信息。

一位乐于助人的用户告诉我,我可以使用表单集来实现它。 我正在尝试使用我的模型 TaskCheck 创建一个表单集。每个 TaskCheck 都有一个属于一个属性的特定任务。所以这就是我创建的:

views.py

def add_taskcheck(request, property_pk, pk):
    tasks = Task.objects.filter(property=property_pk)
    tasks_list = Task.objects.filter(property=property_pk).values('task')
    TaskCheckFormset = formset_factory(TaskCheckForm, extra=0)
    if request.method == 'POST':
        #do something
    else:
        formset = TaskCheckFormset(initial=task_list)

    context = {
        'title':"Add Property Check",
        'task':tasks,
        'reference':property_pk,
        'formset':formset,
    }
    return render(request, 'propertycheck/add-taskcheck.html', context)

我的表单如下所示:

在这种情况下,任务“沙发:检查”不属于实例属性,因此不应该存在,并且字段任务应该作为初始数据预填充。

据我所读here 所知,我应该将初始数据作为字典列表传递。所以我用 .values() 创建了“tasks_list”,并尝试将其作为初始值传递:

tasks_list = Task.objects.filter(property=property_pk).values('task')
formset = TaskCheckFormset(initial=task_list)

所以我的问题是:

如何使用查询集任务预填充这些字段?

如何将行数限制为查询集任务对象的数量?

首先我需要过滤属于特定属性的任务对象。

我尝试过使用模型表单集,但无法传递初始数据。 我也读过this question,但我无法在表单中启动它。

我的models.py:

class Task(models.Model):
    task = models.CharField(max_length=100)
    category = models.ForeignKey(Categories)
    property = models.ManyToManyField(Property)

class TaskCheck(models.Model):
    status = models.CharField(choices=STATUS_CHOICES, default='nd', max_length=50)
    image = models.ImageField(upload_to='task_check', blank=True, null=True)
    notes = models.TextField(max_length=500, blank=True)
    task = models.ForeignKey(Task)
    property_check = models.ForeignKey(Propertycheck)

【问题讨论】:

  • 我不明白你的表单集,formset_factory(TaskCheck, , form=TaskCheckForm, extra=0) 应该会抛出一个错误,因为你传递了一个模型。你应该使用modelformset_factory
  • @dirkgroten 抱歉,modelformset 和 formset 之间的变化我把它留在那里。现在已经修复了

标签: django django-models django-forms formset


【解决方案1】:

如果您有Propertypk,请先获取实际对象:

property = get_object_or_404(Property, pk=property_pk)

然后创建一个包含所有相关TaskCheck 对象的查询集:

qs = TaskCheck.objects.filter(task__property=property).distinct()

最后你可以用qs初始化你的模型表单集:

TaskCheckFormset = modelformset_factory(TaskCheck, form=TaskCheckForm, fields=('status', 'notes'))
formset = TaskCheckFormset(request.POST, queryset=qs)

【讨论】:

  • 我做了这些更改,我又改回了modelformset。我忘记了查询集的一个细节,这个:qs = TaskCheck.objects.filter(task__property=property, property_check=pcheck).distinct()。不幸的是,表格并没有太大变化,它只有一个空行。我现在如何传递初始数据?
  • 您确定您的查询集包含对象吗?表单集的行数应该与查询集中的对象一样多。
  • 它是空的,但这是因为这个 Propertycheck 是空的。使用您的查询集,它确实呈现 3 行,但它还包括属于其他 TaskCheck 的任务
  • 我不明白。您正在显示您希望能够编辑的TaskCheck 对象列表。 taskTaskCheck 的一个字段,它是 Task 模型的 FK。所以选择是所有Task 对象的列表。那里应该显示什么?当前值应该是预先选择的,并且您的表单允许更改它。如果您不希望用户更改它,请将其从您的表单中删除。
  • 你是对的。用户应该无法更改它,我将其删除。我就这样离开了,因为这样我可以看到哪一行属于特定的任务。
猜你喜欢
  • 2017-05-20
  • 1970-01-01
  • 1970-01-01
  • 2011-10-06
  • 1970-01-01
  • 2019-02-05
  • 2016-03-17
  • 2021-06-01
  • 2018-06-08
相关资源
最近更新 更多