2015-02-20 6 views
3

Я отчаянно сейчас, и я не могу понять это. Для меня это должно быть легко сделать, но я не встречал никаких ответов, объясняющих это.Как сохранить Django ModelFormSet?

Две модели без каких-либо внешних ключей между ними:

class Employee(models.Model): 
    surname = models.CharField(max_length=100) 
    name = models.CharField(max_length=100) 


class Salary(models.Model): 
    date = models.DateField(auto_now_add=True) 
    surname = models.CharField(max_length=100) 
    name = models.CharField(max_length=100) 
    salary = models.DecimalField(max_digits=20, decimal_places=2) 

Один modelformset, чтобы сохранить ModelB.

SalaryFormSet = modelformset_factory(Salary, extra=0) 

Тогда в views.py:

def createForm(request): 
    formset = SalaryFormSet(queryset=Employee.objects.all()) 
    return render(request, 'formfile.html', {'formset': formset}) 

def submitForm(request) 
    f = ModelBFormSet(request.POST) 
    if f.is_valid(): 
     f.save() 
     return HttpResponse('Submitted successfully') 
    else: 
     return HttpResponse(f.errors, request.POST) 

В formfile.html:

<form action="submitForm/" method="post"> 
    {{ formset.management_form }} 
    <table> 
     {{ formset }} 
    </table> 
    {% csrf_token %} 
    <input type="submit" value="Submit"> 
</form> 

Как только я ударил Submit, то formset анализируется как недействительные и f.errors состояний (для каждого ряда сотрудников):

<ul class="errorlist"><li>id<ul class="errorlist"><li>Select a valid choice. That choice is not one of the available choices.</li></ul></li></ul> 

I просто хочу иметь фамилию и имя из всех строк в Employee, предварительно загруженных в SalaryFormSet, и я должен вводить зарплату для каждой строки и сохранять их в Зарплата. Записи в Зарплата не должны обновляться, но должна быть создана новая запись.

У модели Employee уже есть записи, созданные с сайта администратора. По мере увеличения зарплаты сотрудников я буду генерировать расчеты с модели зарплаты и получить соответствующую зарплату с последней даты.

Если я изменил запрос на queryset = Salary.objects.none() и изменил SalaryFormSet на extra = 2, шаблон будет пустым. Если я вставляю фамилии, имена и зарплату вручную, набор форм сохраняется правильно. Две новые записи в зарплате. Почему я не могу просто задать имя перед загрузкой (должен ли я загрузить их как str()?) И ​​вручную добавить зарплату?

+0

Не могу понять, что вы пытаетесь сделать здесь вообще. Почему вы передаете запрос modelA к набору форм ModelB? Возможно, менее абстрактный пример поможет. –

+0

@ DanielRoseman Я обновил вопрос, чтобы быть менее абстрактным. – wernerfeuer

+0

Но вы по-прежнему передаете запрос сотрудников на заготовку, что не имеет смысла.И я также не понимаю, почему у вас нет FK между ними: неужели зарплата принадлежит сотруднику? –

ответ

1

Как я уже сказал в комментарии, нет смысла передавать запрос сотрудников для создания формы набора зарплат. Я думаю, что, учитывая, что вы пытаетесь сохранить эти две модели полностью раздельными по какой-либо причине, и каждый раз вы хотите создавать новые экземпляры Salary, вам было бы лучше просто передать набор данных initial.

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

employees = Employee.objects.values('name', 'surname') 
SalaryFormSet = modelformset_factory(Salary, extra=len(employees)) 
formset = SalaryFormSet(initial=employees, queryset=Salary.objects.none()) 
+0

Спасибо за это! Он работает отлично! Я знаю, что метод странный, но это действительно все, что мне нужно! Я отвечу на вопрос с полным примером. – wernerfeuer

1

Это просто, чтобы суммировать ответ на основе решения Даниэля Роземана.

В models.py:

class Employee(models.Model): 
    surname = models.CharField(max_length=100) 
    name = models.CharField(max_length=100) 


class Salary(models.Model): 
    date = models.DateField(auto_now_add=True) 
    surname = models.CharField(max_length=100) 
    name = models.CharField(max_length=100) 
    salary = models.DecimalField(max_digits=20, decimal_places=2) 

В forms.py:

employees = Employee.objects.values('surname', 'name') 
SalaryFormSet = modelformset_factory(Salary, extra=len(employees) 

В views.py:

def createForm(request): 
    formset = SalaryFormSet(initial=employees, queryset=Salary.objects.none()) 
    return render(request, 'formfile.html', {'formset': formset}) 

def submitForm(request) 
    f = ModelBFormSet(request.POST) 
    if f.is_valid(): 
     f.save() 
     return HttpResponse('Submitted successfully') 
    else: 
     return HttpResponse(f.errors, request.POST) 
Смежные вопросы