Как передать исходные данные из QuerySet в набор форм?

Я разрабатываю систему управления недвижимостью, прямо сейчас я работаю над приложением под названием «Проверка свойств», которое в основном сохраняет информацию о проверках, проведенных в отношении некоторых свойств.

Полезный пользователь сказал мне, что я могу добиться этого с помощью наборов форм. Я пытаюсь создать набор форм с моей моделью 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)

Моя форма выглядит так:

Форма TaskCheck В этом случае Задача "Диваны: Проверка" не относится к свойству экземпляра, поэтому ее там быть не должно, а поле Задача должно быть предварительно заполнено как исходные данные.

Насколько я знаю из того, что я прочитал здесь я должен передать исходные данные в виде списка dict. Поэтому я создал «tasks_list» с .values() и попытался передать его как начальный:

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

Итак, мои вопросы:

Как я могу предварительно заполнить эти поля задачами набора запросов?

Как ограничить количество строк количеством объектов задач набора запросов?

Во-первых, мне нужно отфильтровать объекты Task, которые принадлежат определенному свойству.

Я пытался использовать наборы моделей, но не смог передать исходные данные. Я также прочитал этот вопрос, но я могу не инициируйте его внутри форм.

Мои модели.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)

person Luis Silva    schedule 30.12.2019    source источник
comment
Я не понимаю ваш набор форм, formset_factory(TaskCheck, , form=TaskCheckForm, extra=0) должен выдать ошибку, так как вы передаете ему модель. Вы должны использовать modelformset_factory.   -  person dirkgroten    schedule 30.12.2019
comment
@dirkgroten извините, с изменениями между modelformset и formset я оставил это там. Это исправлено сейчас   -  person Luis Silva    schedule 30.12.2019


Ответы (1)


Если у вас есть pk из Property, сначала извлеките фактические объекты:

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)
person dirkgroten    schedule 30.12.2019
comment
Я внес эти изменения, я снова вернулся к modelformset. Я забыл одну деталь в наборе запросов, это: qs = TaskCheck.objects.filter(task__property=property, property_check=pcheck).distinct(). К сожалению, форма не сильно изменилась, в ней всего одна пустая строка. Как мне теперь передать исходные данные? - person Luis Silva; 30.12.2019
comment
Вы уверены, что ваш набор запросов содержит объекты? В наборе форм должно быть столько строк, сколько объектов в вашем наборе запросов. - person dirkgroten; 30.12.2019
comment
Он пуст, но это потому, что этот Propertycheck пуст. С вашим набором запросов он отображает 3 строки, но также включает задачи, принадлежащие другим TaskCheck. - person Luis Silva; 30.12.2019
comment
Я не понимаю. Вы показываете список TaskCheck объектов, которые хотите редактировать. task — это поле TaskCheck, которое является FK для модели Task. Итак, выбор — это список всех Task объектов. Что там должно быть показано? Текущее значение должно быть предварительно выбрано, и ваша форма позволяет его изменить. Если вы не хотите, чтобы пользователь изменил его, удалите его из формы. - person dirkgroten; 30.12.2019
comment
Ты прав. Пользователь не должен иметь возможности изменить его, и я его удалю. Я просто оставил это так, потому что таким образом я мог видеть, какая строка принадлежит определенной задаче. - person Luis Silva; 30.12.2019
comment
Вы также можете отключить поле в своей форме (чтобы оно отображалось, но не редактировалось). Или в своем шаблоне используйте {{ form.instance.task }} для отображения значения, не отображая его в форме. - person dirkgroten; 30.12.2019
comment
Я удалил поле задачи из формы и использовал {{ form.instance.task }} в своем шаблоне. Прямо сейчас форма такая, как я хотел, также я попробовал другие свойства, и она показывает строку для каждой связанной задачи. Теперь я позабочусь о проверке набора форм. После этого я отредактирую свой пост с изменениями и приму ваш ответ. Большое спасибо!!! - person Luis Silva; 30.12.2019