Is there a way to add formset in django-admin without using inline?

86 Views Asked by At

I have a model called Employee which is defined as follows:

class Employee(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    name = models.CharField("Name", max_length=255)
    address = models.CharField("Address", max_length=255)
    department = models.ForeignKey(Department, on_delete=models.SET_NULL)
    team = models.ForeignKey(Team, on_delete=models.SET_NULL)
    position = models.ForeignKey(Position, on_delete=models.SET_NULL)

Is there a way to add multiple name and address of employee for the same department, team and position in django-admin form? I want something like formset including fields name and address for the model Employee where you can enter the department, team and postion and just add the formsets multiple times like how you would do for inlines.

I have not tried anything as of yet.

2

There are 2 best solutions below

1
On

you can do this in Django admin by using inline formsets. In your case, you want to allow multiple name and address entries for the same department, team, and position in the Django admin form.

from django import forms
from django.contrib import admin
from django.forms.models import inlineformset_factory
from .models import Employee, Department, Team, Position

class EmployeeInlineForm(forms.ModelForm):
    class Meta:
        model = Employee
        fields = ['name', 'address']

EmployeeInlineFormSet = inlineformset_factory(
    Department,  # Parent model (change to Team or Position as needed)
    Employee,
    form=EmployeeInlineForm,
    extra=1,  # Number of empty forms to display
    can_delete=True,
)

class EmployeeInline(admin.TabularInline):  # Use 'StackedInline' for a different layout
    model = Employee
    formset = EmployeeInlineFormSet
    extra = 1  # Number of empty forms to display

class DepartmentAdmin(admin.ModelAdmin):
    inlines = [EmployeeInline]

admin.site.register(Department, DepartmentAdmin)
1
On

or you can try this way:

from django.forms import formset_factory

class EmployeeForm(forms.ModelForm):
    class Meta:
        model = Employee
        fields = ('name', 'address', 'department', 'team', 'position')

# Create a formset for the EmployeeForm
formset_class = formset_factory(EmployeeForm, extra=0)

# Use the formset in your Django-admin
# Assuming you have a template named 'admin/employee_formset.html'
template_name = 'admin/employee_formset.html'

In your admin.py file, jus t render the formset with the following code:

from django.contrib import admin
from .forms import formset_class

@admin.register(Employee)
class EmployeeAdmin(admin.ModelAdmin):
    form = formset_class

    def get_form(self, request, *args, **kwargs):
        return super().get_form(request, *args, **kwargs)

now just in the admin/employee_formset.html template, render the formset using the following code:

{% block content %}
    {{ formset.management_form }}
    {% for form in formset %}
        {{ form }}
    {% endfor %}
{% endblock content %}

This will create a formset with inline forms for the Employee model, allowing you to enter multiple names and addresses for the same department, team, and position in Django-admin.