Abhishek Roka
Abhishek Roka

How I'm Implementing Dynamic Job Application Forms in My Placement Portal


After my stakeholder meeting, I had a much clearer understanding of what the Placement Officer needs from my Placement Portal.

One of the most important requirements was the ability to create dynamic application forms for individual job postings.

Different companies can ask students for different information.

One company might require CGPA and backlogs.

Another might ask for a portfolio URL or a certification.

I don't want to create a new database field or modify application logic every time a company needs a new question.

So, after deciding how I want the dynamic form system to work, I started implementing it step by step.

This is Part 1 of that implementation.

Step 1: Creating the Attribute Table

The first step was to create an Attribute table.

The purpose of this table is to define what an attribute actually is.

At the moment, the important pieces of information are:

The attribute name represents what information is being collected.

The data type tells the application how that information should be treated.

For example, an attribute could represent something like:

The data type becomes particularly important because dynamic forms aren't just about displaying fields.

The system also needs to understand what kind of value each field is supposed to contain.

Step 2: Connecting Attributes to Job Applications

After creating the Attribute table, the next step was connecting it with the models responsible for jobs and applications.

This is where I introduced two important concepts:

Job Attribute

and

Application Attribute Value

The Job Attribute represents an attribute selected for a particular job posting.

It also contains additional configuration such as whether the field is required.

For example, a Placement Officer might configure:

CGPA → Required

while another field could be:

Portfolio URL → Optional

This allows the same attribute definition to be reused across different job postings while still allowing each job to configure how that field behaves.

Why Application Attribute Value Snapshots the Attribute

There is an important database design decision here.

For Job Attribute, the Attribute is connected using a foreign key.

But for Application Attribute Value, I decided to snapshot the attribute instead of keeping a foreign key relationship to the current Attribute definition.

Why?

Because an application represents what the student submitted at a particular point in time.

Imagine a student applies for a job today.

The application contains:

CGPA → 8.2

Later, the global definition of that attribute changes.

I don't want an old application to suddenly depend on whatever the current Attribute definition happens to look like.

The application should preserve the information that existed when the student applied.

This is the same principle behind preserving historical application data rather than relying entirely on the current state of related records.

The application becomes a record of what actually happened.

Step 3: Connecting Everything Through Django Admin

Once the models were structured, the next step was connecting them inside Django Admin.

I connected:

Job Attribute → Job

as an inline.

And similarly:

Application Attribute Value → Application

as an inline.

This gives me a practical way to test the complete backend workflow before building the frontend.

The relationship now becomes conceptually:

Attribute → Job Attribute → Job

and:

Application → Application Attribute Value

This lets me create job-specific fields and inspect how those values are stored when working with applications.

Step 4: Testing the Workflow Before Building the Frontend

My Django Admin panel is now ready for testing.

This is an important part of my development process.

Before spending time building the frontend experience, I want to verify that the backend data model actually supports the workflow I have designed.

Through Django Admin, I can test things such as:

If the underlying model design doesn't work correctly, building a polished frontend on top of it won't solve the problem.

It will only make the problem more expensive to fix.

So for this phase, Django Admin acts as my testing interface.

Step 5: Building the Placement Officer Experience

Once the backend workflow is working correctly, the next step is the frontend.

This is where the technical implementation needs to disappear behind a simple user experience.

The Placement Officer shouldn't have to think about:

They should simply be able to:

  1. Create a job posting.
  2. Select the information required from students.
  3. Mark fields as required when necessary.
  4. Save the job.
  5. Publish it.

The complexity should remain inside the system.

The interface should feel effortless.

Backend Complexity, Simple User Experience

This is one of the things I am beginning to appreciate while building this Placement Portal.

A feature can have a relatively complicated backend design while providing a very simple experience to the user.

For the dynamic form system, I currently have to think about:

But the Placement Officer shouldn't need to understand any of that.

They should just see a form builder that makes sense.

That's the real goal of this implementation.

What Comes Next?

This is only Part 1 of the dynamic form implementation.

The backend structure and Django Admin workflow are the first pieces.

The next major step is building the frontend experience for the Placement Officer.

That's where I'll turn the underlying database and API design into an interface that allows a Placement Officer to create a job and configure its application form without needing to understand how the system works internally.

And that is where I expect the next set of design problems to appear.

Final Thoughts

The stakeholder meeting gave me the requirements.

Now I'm translating those requirements into actual system design.

My current implementation path is:

Attribute → Job Attribute → Job → Application → Application Attribute Value

Then:

Django Admin → Backend validation → Frontend experience

I'm deliberately building this in stages.

First, make the data model work.

Then, test the workflow.

Then, build the experience around it.

Because a good dynamic form isn't just about making fields configurable.

It's about building a system flexible enough for different requirements while keeping the experience simple for the person creating the job.