JimJay
JimJay

Reputation: 349

Django formset difficulties

I am building a Django application which has Company, Employee and Ext models as so:

class Company(models.Model):
    user = models.ForeignKey(User)
    name = models.CharField(max_length=30)
    ...

class Employee(models.Model):
    company = models.ForeignKey(Company)
    emp_name = models.CharField(max_length=15)
    ...

class Ext(models.Model):
    employee = models.ForeignKey(Employee)
    expiry_date = models.DateField(default=lambda:datetime.datetime.now()+datetime.timedelta(days=60))
    ...

I have the following forms for these models:

class CompanyForm(ModelForm):
    class Meta:
        model = Company

class EmployeeForm(ModelForm):
    class Meta:
        model = Employee
        exclude = ('company')

class ExtForm(ModelForm):
    class Meta:
        model = Prize
    exclude = ('employee')

class EmployeeFormSet(BaseFormSet):

    def clean(self):
        if any(self.errors):
            return

        names = []

        for i in range(0, self.total_form_count()):
            form = self.forms[i]
            e_name = form.cleaned_data['emp_name']

            if e_name in names:
                raise forms.ValidationErrors("Employees must have unique names")

            names.append(e_name)

I came across "Django Dynamic Formset" (http://code.google.com/p/django-dynamic-formset/) which I have sucessfully got working to allow me to add multiple employee forms to my employee formset dynamically in the template:

<script type="text/javascript" src="{% static "js/jquery-1.4.2.min.js" %}"></script>
<script type="text/javascript" src="{% static "js/jquery.formset.js" %}"></script>
<script type="text/javascript">
    $(function() {
        $('#eForm tbody tr').formset();
    })
</script>
...
<form id="eForm" method="post" action="">
    {% csrf_token %}
            <table border="0" cellpadding="0" cellspacing="0">
            <tbody>
            {% for form in employee_formset.forms %}
            <tr>
                        <td>{{ form.emp_name }}</td></br>
                        ...
                    </tr>
                    {% endfor %}
                    </tbody>
                </table>
        {{ employee_formset.management_form }}
        <input id="submit" type="submit" name="submit" value="Submit" />
</form>

My goal is to be able to add a single Company, one or more Employees associated with this Company, and a single Ext object associated with just one of these Employees, all in a single submission.

I'm not sure about how to tackle this. Can anyone point me in the right direction?

Upvotes: 1

Views: 1266

Answers (1)

Ben Rosnick
Ben Rosnick

Reputation: 148

If your ExtModel() doesn't require any user input, then:

forms.py

class CompanyForm(ModelForm):
    class Meta:
        model = Company

class EmployeeForm(ModelForm):

    ext = forms.BooleanField(initial=False)

    class Meta:
        model = Employee

Then, in your views, create a single instance of CompanyForm, and use inlineformset_factory(Company, Employee, form=EmployeeForm).

When saving the formset:

if formset.is_valid():
    for form in formset:
        employee = form.save()
        if form.cleaned_data['ext'] == True
            Ext(employee=employee, ...).save()

If you need user input for more Ext fields, and if it's the same input for each employee for any given post, then render an additional form for that data. If it's different Ext data for different employees, then it's going to be more complicated.

Upvotes: 1

Related Questions