dj-dynamic-form 1.0.0
A Django package that empowers developers to create, manage, and process dynamic forms within Django applications.
License: MIT
Requires Python: >=3.9
Keywords: django, django dynamic form, dynamic, dynamic form, form

# Welcome to the Django Dynamic Form Documentation!

[![License](https://img.shields.io/github/license/lazarus-org/dj-dynamic-form)](https://github.com/lazarus-org/dj-dynamic-form/blob/main/LICENSE)
[![PyPI Release](https://img.shields.io/pypi/v/dj-dynamic-form)](https://pypi.org/project/dj-dynamic-form/)
[![Pylint Score](https://img.shields.io/badge/pylint-10/10-brightgreen?logo=python&logoColor=blue)](https://www.pylint.org/)
[![Supported Python Versions](https://img.shields.io/pypi/pyversions/dj-dynamic-form)](https://pypi.org/project/dj-dynamic-form/)
[![Supported Django Versions](https://img.shields.io/pypi/djversions/dj-dynamic-form)](https://pypi.org/project/dj-dynamic-form/)
[![Pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=yellow)](https://github.com/pre-commit/pre-commit)
[![Open Issues](https://img.shields.io/github/issues/lazarus-org/dj-dynamic-form)](https://github.com/lazarus-org/dj-dynamic-form/issues)
[![Last Commit](https://img.shields.io/github/last-commit/lazarus-org/dj-dynamic-form)](https://github.com/lazarus-org/dj-dynamic-form/commits/main)
[![Languages](https://img.shields.io/github/languages/top/lazarus-org/dj-dynamic-form)](https://github.com/lazarus-org/dj-dynamic-form)
[![Coverage](https://codecov.io/gh/lazarus-org/dj-dynamic-form/branch/main/graph/badge.svg)](https://codecov.io/gh/lazarus-org/dj-dynamic-form)

[`dj-dynamic-form`](https://github.com/lazarus-org/dj-dynamic-form/) is a Django package developed by Lazarus that empowers developers to create, manage, and process dynamic forms within Django applications.

It provides a robust framework for defining flexible form structures, fields, and submissions, with built-in support for Django Admin and RESTful API integration via Django REST Framework.

## Project Detail

- Language: Python >= 3.9
- Framework: Django >= 4.2
- Django REST Framework: >= 3.14

## Documentation Overview

The documentation is organized into the following sections:

- **[Quick Start](#quick-start)**: Get up and running quickly with basic setup instructions.
- **[API Guide](#api-guide)**: Detailed information on available APIs and endpoints.
- **[Admin Panel](#admin-panel)**: Detailed information on available features and functionalities of Admin Panel.
- **[Settings](#settings)**: Configuration options and settings you can customize.

---

# Quick Start

This section provides a fast and easy guide to getting the `dj-dynamic-form` package up and running in your Django
project.
Follow the steps below to quickly set up the package and start using the package.

## 1. Install the Package

**Option 1: Using `pip` (Recommended)**

Install the package via pip:

```bash
$ pip install dj-dynamic-form
```

**Option 2: Using `Poetry`**

If you're using Poetry, add the package with:

```bash
$ poetry add dj-dynamic-form
```

**Option 3: Using `pipenv`**

If you're using pipenv, install the package with:

```bash
$ pipenv install dj-dynamic-form
```

## 2. Install Django REST Framework

You need to install Django REST Framework for API support. If it's not already installed in your project, you can
install it via pip:

**Using pip:**

```bash
$ pip install djangorestframework
```

## 3. Add to Installed Apps

After installing the necessary packages, ensure that both `rest_framework` and `dynamic_form` are added to
the `INSTALLED_APPS` in your Django `settings.py` file:

```python
INSTALLED_APPS = [
    # ...
    "rest_framework",

    "dynamic_form",
    # ...
]
```

### 4. (Optional) Configure API Filters

To enable filtering through the API, install ``django-filter``, include ``django_filters`` in your ``INSTALLED_APPS``.

Install ``django-filter`` using one of the above methods:

**Using pip:**

```bash
$ pip install django-filter
```

Add `django_filters` to your `INSTALLED_APPS`:

```python
INSTALLED_APPS = [
   # ...
   "django_filters",
   # ...
]
```

You can also define your custom `FilterClass` and reference it in settings if needed. This allows you to customize the filtering behavior according to your requirements. for more detailed info, refer to the [Settings](#settings) section.



## 5. Apply Migrations

Run the following command to apply the necessary migrations:

```shell
python manage.py migrate
```

## 6. Add project URL routes

You can use the API or the Django Template View for Dashboard by Including them in your project’s `urls.py` file:

```python
from django.urls import path, include

urlpatterns = [
    # ...
    path("dynamic_form/", include("dynamic_form.api.routers.main")),
    # ...
]
```

----

# API Guide

This section provides a detailed overview of the `dj-dynamic-form` API, enabling administrators and users to manage dynamic forms, fields , field types, and submissions within Django and Django REST Framework (DRF) applications. The API exposes several primary endpoints grouped by functionality:

- **`/admin/forms/`**, **`/admin/forms/{form_id}/fields/`**, **`/admin/field-types/`**, **`/admin/submissions/`** - Admin APIs for managing all forms, related fields, field types and submissions (requires admin permissions).
- **`/forms/`**, **`/fields/`**, **`/field-types/`**, **`/submissions/`** - User APIs for interacting with forms, fields and submitting data.
---

## Admin API Management

The admin endpoints allow admin users (default permission is set to `IsAdminUser`) to fully manage dynamic forms, fields, and submissions. Each endpoint supports standard CRUD operations with configurable permissions.

### Dynamic Forms (`/admin/forms/`)

- **List Forms**:

  Fetches all dynamic forms. Controlled by `DYNAMIC_FORM_API_ADMIN_DYNAMIC_FORM_ALLOW_LIST`.
- **Retrieve a Form**:

  Retrieves a specific form by ID. Controlled by `DYNAMIC_FORM_API_ADMIN_DYNAMIC_FORM_ALLOW_RETRIEVE`.
- **Create a Form**:

  Creates a new form. Controlled by `DYNAMIC_FORM_API_ADMIN_DYNAMIC_FORM_ALLOW_CREATE`.
- **Update a Form**:

  Updates an existing form (e.g., toggling `is_active`). Controlled by `DYNAMIC_FORM_API_ADMIN_DYNAMIC_FORM_ALLOW_UPDATE`.
- **Delete a Form**:

  Deletes an existing form. Controlled by `DYNAMIC_FORM_API_ADMIN_DYNAMIC_FORM_ALLOW_DELETE`.

### Dynamic Fields (`/admin/forms/{form_id}/fields/`)

- **List Fields**:

  Fetches all fields for a specific form. Controlled by `DYNAMIC_FORM_API_ADMIN_DYNAMIC_FIELD_ALLOW_LIST`.
- **Retrieve a Field**:

  Retrieves a specific field by ID within a form. Controlled by `DYNAMIC_FORM_API_ADMIN_DYNAMIC_FIELD_ALLOW_RETRIEVE`.
- **Create a Field**:

  Creates a new field for the specified form. Controlled by `DYNAMIC_FORM_API_ADMIN_DYNAMIC_FIELD_ALLOW_CREATE`.
- **Update a Field**:

  Updates an existing field (e.g., changing `is_required`). Controlled by `DYNAMIC_FORM_API_ADMIN_DYNAMIC_FIELD_ALLOW_UPDATE`.
- **Delete a Field**:

  Deletes an existing field from the form. Controlled by `DYNAMIC_FORM_API_ADMIN_DYNAMIC_FIELD_ALLOW_DELETE`.

### Field Types (`/admin/field-types/`)

- **List Field Types**:

  Fetches all field types. Controlled by `DYNAMIC_FORM_API_ADMIN_FIELD_TYPE_ALLOW_LIST`.
- **Retrieve a Field Type**:

  Retrieves a specific field type by ID. Controlled by `DYNAMIC_FORM_API_ADMIN_FIELD_TYPE_ALLOW_RETRIEVE`.
- **Create a Field Type**:

  Creates a new field type. Controlled by `DYNAMIC_FORM_API_ADMIN_FIELD_TYPE_ALLOW_CREATE`.
- **Update a Field Type**:

  Updates an existing field type (e.g., changing `is_active`). Controlled by `DYNAMIC_FORM_API_ADMIN_FIELD_TYPE_ALLOW_UPDATE`.
- **Delete a Field Type**:

  Deletes an existing field type. Controlled by `DYNAMIC_FORM_API_ADMIN_FIELD_TYPE_ALLOW_DELETE`.


### Form Submissions (`/admin/form-submissions/`)

- **List Submissions**:

  Fetches all submissions. Controlled by `DYNAMIC_FORM_API_ADMIN_FORM_SUBMISSION_ALLOW_LIST`.
- **Retrieve a Submission**:

  Retrieves a specific submission by ID. Controlled by `DYNAMIC_FORM_API_ADMIN_FORM_SUBMISSION_ALLOW_RETRIEVE`.
- **Create a Submission**:

  Creates a new submission (admin use case). Controlled by `DYNAMIC_FORM_API_ADMIN_FORM_SUBMISSION_ALLOW_CREATE`.
- **Update a Submission**:

  Updates an existing submission. Controlled by `DYNAMIC_FORM_API_ADMIN_FORM_SUBMISSION_ALLOW_UPDATE`.
- **Delete a Submission**:

  Deletes an existing submission. Controlled by `DYNAMIC_FORM_API_ADMIN_FORM_SUBMISSION_ALLOW_DELETE`.

---

## User API Management

The user endpoints allow authenticated users to interact with forms and manage their own submissions.

### Forms (`/forms/`)

- **List Forms**:

  Fetches all active forms available to users. Controlled by `DYNAMIC_FORM_API_DYNAMIC_FORM_ALLOW_LIST`.
- **Retrieve a Form**:

  Retrieves a specific form by ID. Controlled by `DYNAMIC_FORM_API_DYNAMIC_FORM_ALLOW_RETRIEVE`.

### Fields (`/fields/`)

- **List Fields**:

  Fetches all fields available to users. Controlled by `DYNAMIC_FORM_API_DYNAMIC_FIELD_ALLOW_LIST`.
- **Retrieve a Field**:

  Retrieves a specific field by ID. Controlled by `DYNAMIC_FORM_API_DYNAMIC_FIELD_ALLOW_RETRIEVE`.

### Field Types (`/field-types/`)

- **List Field Types**:

  Fetches all field types available to users. Controlled by `DYNAMIC_FORM_API_FIELD_TYPE_ALLOW_LIST`.
- **Retrieve a Field**:

  Retrieves a specific field by ID. Controlled by `DYNAMIC_FORM_API_FIELD_TYPE_ALLOW_RETRIEVE`.


### Form Submissions (`/form-submissions/`)

- **List Submissions**:

  Fetches the user's own submissions. Controlled by `DYNAMIC_FORM_API_FORM_SUBMISSION_ALLOW_LIST`.
- **Retrieve a Submission**:

  Retrieves a specific user submission by ID. Controlled by `DYNAMIC_FORM_API_FORM_SUBMISSION_ALLOW_RETRIEVE`.
- **Create a Submission**:

  Submits data for a form. Controlled by `DYNAMIC_FORM_API_FORM_SUBMISSION_ALLOW_CREATE`.
- **Update a Submission**:

  Updates an existing user submission. Controlled by `DYNAMIC_FORM_API_FORM_SUBMISSION_ALLOW_UPDATE`.
- **Delete a Submission**:

  Deletes an existing user submission. Controlled by `DYNAMIC_FORM_API_FORM_SUBMISSION_ALLOW_DELETE`.

---

## Response Fields

### Forms
- `id`: Unique identifier of the form (integer).
- `name`: Name of the form (string).
- `description`: Description of the form (string).
- `is_active`: Boolean indicating if the form is active (boolean).
- `fields`: List of associated fields (nested array of field objects, included in retrieve or list responses).
- `created_at`: Timestamp when the form was created (ISO 8601 string).
- `updated_at`: Timestamp when the form was last updated (ISO 8601 string).

### Fields
- `id`: Unique identifier of the field (integer).
- `form`: ID of the associated form (integer; not included in nested responses under forms).
- `name`: Field name, unique within the form (string).
- `label`: Human-readable label for the field (string).
- `field_type`: The associated field type (nested object with `id`, `name`, `label`, `description`, `created_at`, and `is_active`).
- `is_required`: Boolean indicating if the field is mandatory (boolean).
- `choices`: List of predefined options for the field, if applicable (array or null).
- `default_value`: Default value for the field, if set (string or null).
- `validation_rules`: Custom validation rules for the field, if any (object or null).
- `order`: Order of the field within the form (integer).

### Field Types
- `id`: Unique identifier of the field type (integer).
- `name`: Name of the field type (e.g., "text", "boolean") (string).
- `label`: Human-readable label for the field type (string).
- `description`: Description of the field type (string).
- `created_at`: Timestamp when the field type was created (ISO 8601 string).
- `is_active`: Boolean indicating if the field type is active (boolean).

### Form Submissions
- `id`: Unique identifier of the submission (integer).
- `form`: The associated form (nested object with full form details, including `id`, `fields`, `name`, `description`, `is_active`, `created_at`, and `updated_at`).
- `user`: The submitting user (nested object with `username` and `email`, or null if anonymous).
- `submitted_data`: JSON object containing the submitted field values (object with field names as keys).
- `submitted_at`: Timestamp when the submission was made (ISO 8601 string).

---

### Example Responses

**List Forms**:
```text
GET /forms/ or /admin/forms

Response:
HTTP/1.1 200 OK
Content-Type: application/json
{
    "count": 3,
    "next": null,
    "previous": null,
    "results": [
        {
            "id": 1,
            "fields": [
                {
                    "id": 1,
                    "field_type": {
                        "id": 1,
                        "name": "text",
                        "label": "Text Field",
                        "description": "A single-line text input.",
                        "created_at": "2025-03-24T17:15:23.628891Z",
                        "is_active": true
                    },
                    "name": "first_name",
                    "label": "First Name",
                    "is_required": false,
                    "choices": null,
                    "default_value": null,
                    "validation_rules": null,
                    "order": 0,
                    "form": 1
                },
                {
                    "id": 3,
                    "field_type": {
                        "id": 1,
                        "name": "text",
                        "label": "Text Field",
                        "description": "A single-line text input.",
                        "created_at": "2025-03-24T17:15:23.628891Z",
                        "is_active": true
                    },
                    "name": "last_name",
                    "label": "Last Name",
                    "is_required": false,
                    "choices": null,
                    "default_value": null,
                    "validation_rules": null,
                    "order": 0,
                    "form": 1
                },
            ],
            "name": "Test Form",
            "description": "some description",
            "is_active": true,
            "created_at": "2025-03-24T18:31:21.458061Z",
            "updated_at": "2025-03-24T18:31:21.458097Z"
        }
    ]
}
```

**Create a Form**:
```text
POST /admin/forms/
Content-Type: application/json

{
    "name": "Test Form",
    "description": "some description",
    "is_active": true
}

Response:
HTTP/1.1 201 Created
Content-Type: application/json

{
    "id": 2,
    "fields": [],
    "name": "Test Form",
    "description": "some description",
    "is_active": true,
    "created_at": "2025-04-01T07:23:56.582322Z",
    "updated_at": "2025-04-01T07:23:56.582351Z"
}
```

---

**List Fields**:
```text
GET /fields/ or admin/forms/1/fields/
Response:
HTTP/1.1 200 OK
Content-Type: application/json

{
    "count": 5,
    "next": null,
    "previous": null,
    "results": [
        {
            "id": 1,
            "field_type": {
                "id": 1,
                "name": "text",
                "label": "Text Field",
                "description": "A single-line text input.",
                "created_at": "2025-03-24T17:15:23.628891Z",
                "is_active": true
            },
            "name": "first_name",
            "label": "First Name",
            "is_required": false,
            "choices": null,
            "default_value": null,
            "validation_rules": null,
            "order": 0,
            "form": 1
        },
    ]
}
```

---

**Create a Field**:
```text
POST /admin/forms/1/fields/
Content-Type: application/json

{
    "field_type_id": 1,
    "name": "email",
    "label": "Email Address",
    "is_required": true
}

Response:
HTTP/1.1 201 Created
Content-Type: application/json

{
    "id": 6,
    "field_type": {
        "id": 1,
        "name": "text",
        "label": "Text Field",
        "description": "A single-line text input.",
        "created_at": "2025-03-24T17:15:23.628891Z",
        "is_active": true
    },
    "name": "email",
    "label": "Email Address",
    "is_required": false,
    "choices": null,
    "default_value": null,
    "validation_rules": null,
    "order": 3,
    "form": 1
}
```

**List Field Types**:
```text
GET /field-types/ or admin/field-types/
Response:
HTTP/1.1 200 OK
Content-Type: application/json

{
    "count": 10,
    "next": null,
    "previous": null,
    "results": [
        {
            "id": 4,
            "name": "boolean",
            "label": "Boolean Field",
            "description": "A true/false checkbox.",
            "created_at": "2025-03-24T17:15:23.633779Z",
            "is_active": true
        },
        {
            "id": 8,
            "name": "checkbox",
            "label": "Checkbox Field",
            "description": "A checkbox input.",
            "created_at": "2025-03-24T17:15:23.637771Z",
            "is_active": true
        },
    ]
}
```

**Create a Field Type**:
```text
POST /admin/field-types/
Content-Type: application/json

{
    "name": "boolean",
    "label": "Boolean Filed",
    "description": "A true/false checkbox.",
    "is_active": true
}

Response:
HTTP/1.1 201 Created
Content-Type: application/json
{
    "id": 4,
    "name": "boolean",
    "label": "Boolean Field",
    "description": "A true/false checkbox.",
    "created_at": "2025-03-24T17:15:23.633779Z",
    "is_active": true
}
```
---
**List Form Submissions**:
```text
GET /submissions/ or admin/submissions/
Response:
HTTP/1.1 200 OK
Content-Type: application/json

{
    "count": 2,
    "next": null,
    "previous": null,
    "results": [
        {
            "id": 3,
            "form": {
                "id": 1,
                "fields": [
                    {
                        "id": 1,
                        "field_type": {
                            "id": 1,
                            "name": "text",
                            "label": "Text Field",
                            "description": "A single-line text input.",
                            "created_at": "2025-03-24T17:15:23.628891Z",
                            "is_active": true
                        },
                        "name": "first_name",
                        "label": "First Name",
                        "is_required": false,
                        "choices": null,
                        "default_value": null,
                        "validation_rules": null,
                        "order": 0,
                        "form": 1
                    },
                    {
                        "id": 2,
                        "field_type": {
                            "id": 1,
                            "name": "text",
                            "label": "Text Field",
                            "description": "A single-line text input.",
                            "created_at": "2025-03-24T17:15:23.628891Z",
                            "is_active": true
                        },
                        "name": "last_name",
                        "label": "Last Name",
                        "is_required": true,
                        "choices": null,
                        "default_value": null,
                        "validation_rules": null,
                        "order": 1,
                        "form": 1
                    },
                    {
                        "id": 5,
                        "field_type": {
                            "id": 2,
                            "name": "number",
                            "label": "Number Field",
                            "description": "A numeric input.",
                            "created_at": "2025-03-24T17:15:23.631288Z",
                            "is_active": true
                        },
                        "name": "address",
                        "label": "Address",
                        "is_required": false,
                        "choices": null,
                        "default_value": null,
                        "validation_rules": null,
                        "order": 3,
                        "form": 1
                    },
                    {
                        "id": 6,
                        "field_type": {
                            "id": 1,
                            "name": "text",
                            "label": "Text Field",
                            "description": "A single-line text input.",
                            "created_at": "2025-03-24T17:15:23.628891Z",
                            "is_active": true
                        },
                        "name": "email",
                        "label": "Email Address",
                        "is_required": false,
                        "choices": null,
                        "default_value": null,
                        "validation_rules": null,
                        "order": 3,
                        "form": 1
                    }
                ],
                "name": "Login Form",
                "description": "some desc",
                "is_active": true,
                "created_at": "2025-03-24T18:31:21.458061Z",
                "updated_at": "2025-03-24T18:31:21.458097Z"
            },
            "user": {
                "username": "mehrshad",
                "email": ""
            },
            "submitted_data": {
                "last_name": "some last name"
            },
            "submitted_at": "2025-03-27T20:13:22.504769Z"
        },
    ]
}
```
---

**Create a Submission**:
```text
POST /submissions/
Content-Type: application/json

{
    "form_id": 1,
    "submitted_data": {"email": "user@example.com"}
}

Response:
HTTP/1.1 201 Created
Content-Type: application/json

{
    "id": 1,
    "form": {
        "id": 1,
        "fields": [
            {
                "id": 1,
                "field_type": {
                    "id": 1,
                    "name": "text",
                    "label": "Text Field",
                    "description": "A single-line text input.",
                    "created_at": "2025-03-24T17:15:23.628891Z",
                    "is_active": true
                },
                "name": "first_name",
                "label": "First Name",
                "is_required": false,
                "choices": null,
                "default_value": null,
                "validation_rules": null,
                "order": 0,
                "form": 1
            },
            {
                "id": 2,
                "field_type": {
                    "id": 1,
                    "name": "text",
                    "label": "Text Field",
                    "description": "A single-line text input.",
                    "created_at": "2025-03-24T17:15:23.628891Z",
                    "is_active": true
                },
                "name": "last_name",
                "label": "Last Name",
                "is_required": true,
                "choices": null,
                "default_value": null,
                "validation_rules": null,
                "order": 1,
                "form": 1
            },
            {
                "id": 5,
                "field_type": {
                    "id": 2,
                    "name": "number",
                    "label": "Number Field",
                    "description": "A numeric input.",
                    "created_at": "2025-03-24T17:15:23.631288Z",
                    "is_active": true
                },
                "name": "address",
                "label": "Address",
                "is_required": false,
                "choices": null,
                "default_value": null,
                "validation_rules": null,
                "order": 3,
                "form": 1
            },
            {
                "id": 6,
                "field_type": {
                    "id": 1,
                    "name": "text",
                    "label": "Text Field",
                    "description": "A single-line text input.",
                    "created_at": "2025-03-24T17:15:23.628891Z",
                    "is_active": true
                },
                "name": "email",
                "label": "Email Address",
                "is_required": false,
                "choices": null,
                "default_value": null,
                "validation_rules": null,
                "order": 3,
                "form": 1
            }
        ],
        "name": "Login Form",
        "description": "some desc",
        "is_active": true,
        "created_at": "2025-03-24T18:31:21.458061Z",
        "updated_at": "2025-03-24T18:31:21.458097Z"
    },
    "user": null,
    "submitted_data": {"email": "user@example.com"},
    "submitted_at": "2025-03-31T12:00:00+00:00"
}
```

---

## Throttling

The API includes a built-in throttling mechanism that limits the number of requests a user can make based on their role.
You can customize these throttle limits in the settings file.

To specify the throttle rates for regular users (maybe authenticated or not) and staff members, add the following in your settings:

```ini
DYNAMIC_FORM_AUTHENTICATED_USER_THROTTLE_RATE = "100/day"
DYNAMIC_FORM_STAFF_USER_THROTTLE_RATE = "60/minute"
```

These settings define the request limits for regular and admin users.

---


## Ordering, Filtering and Search

The API supports ordering, filtering and searching for all endpoints.

Options include:

- **Ordering**: Results can be ordered by fields dedicated to each ViewSet.

- **Filtering**: By default, the filtering feature is not included. If you want to use this, you need to install `django-filter` first, then add `django_filters` to your `INSTALLED_APPS` and provide the path to your custom filter class .

- **Search**: You can search for any fields that is used is search fields.

These fields can be customized by adjusting the related configurations in your Django settings.

---

## Pagination

The API uses limit-offset pagination, allowing customization of minimum, maximum, and default page size limits.

---

## Permissions

- **User API (`/dynamic_form/`)**: Available to all anonymous users (`AllowAny`) by default, but can be customized using the related API setting.
- **Admin API (`dynamic_form/admin/`)**: Restricted to staff and superusers (`IsAdminUser`) by default, but can be customized using `DYNAMIC_FORM_API_ADMIN_PERMISSION_CLASS`.

---

## Parser Classes

The API supports multiple parser classes that control how data is processed. The default parsers include:

- ``JSONParser``
- ``MultiPartParser``
- ``FormParser``

You can modify parser classes by updating the API settings to include additional parsers or customize the existing ones
to suit your project.

---

Each feature can be configured through Django settings. For further details, refer to the [Settings](#settings) section.

----

# Admin Panel

This section provides a comprehensive guide on the functionality of the Django admin panels for managing tables.

## Admin Site

If you are using a **custom admin site** in your project, you must pass your custom admin site configuration in your
Django settings. Otherwise, Django may raise the following error during checks or the ModelAdmin will not accessible in
the Admin panel.

To resolve this, In your ``settings.py``, add the following setting to specify the path to your custom admin site class
instance.

example of a custom Admin Site:

```python
from django.contrib.admin import AdminSite


class CustomAdminSite(AdminSite):
    site_header = "Custom Admin"
    site_title = "Custom Admin Portal"
    index_title = "Welcome to the Custom Admin Portal"


# Instantiate the custom admin site as example
example_admin_site = CustomAdminSite(name="custom_admin")
```

and then reference the instance like this:

```python
DYNAMIC_FORM_ADMIN_SITE_CLASS = "path.to.example_admin_site"
```

This setup allows `dj-dynamic-form` to use your custom admin site for its Admin interface, preventing any errors and
ensuring a smooth integration with the custom admin interface.

# Dynamic Forms Admin Panel

The Django admin panel for `dj-dynamic-form` provides a robust interface for administrators to manage dynamic forms, field types, fields, and form submissions. Below are the features and configurations for each admin class, designed to streamline oversight and maintenance of these resources.

---

## DynamicFormAdmin

The `DynamicFormAdmin` class provides an admin interface for managing `DynamicForm` records.

### Features

#### List Display
The list view for dynamic form records includes:
- **ID**: The unique identifier for the form (integer).
- **Name**: The name of the form (string).
- **Is Active**: A boolean indicating whether the form is active (boolean).
- **Created At**: Timestamp when the form was created (datetime).
- **Updated At**: Timestamp when the form was last updated (datetime).

#### List Display Links
The following fields are clickable links to the detailed view:
- **ID**: Links to the detailed view of the form.
- **Name**: Links to the detailed view of the form.

#### Filtering
Admins can filter the list of forms based on:
- **Created At**: Filter by creation date.
- **Updated At**: Filter by last update date.

#### Search Functionality
Admins can search for forms using:
- **Name**: Search by the form’s name.
- **Description**: Search by the form’s description.

#### Ordering
Records are ordered by:
- **Created At**: Descending order (newest first).

#### Read-Only Fields
The following fields are marked as read-only in the detailed view:
- **Created At**: The timestamp when the form was created.
- **Updated At**: The timestamp when the form was last updated.

---

## FieldTypeAdmin

The `FieldTypeAdmin` class provides an admin interface for managing `FieldType` records.

### Features

#### List Display
The list view for field type records includes:
- **ID**: The unique identifier for the field type (integer).
- **Name**: The name of the field type (e.g., "text", "boolean") (string).
- **Label**: The human-readable label for the field type (string).
- **Is Active**: A boolean indicating whether the field type is active (boolean).
- **Created At**: Timestamp when the field type was created (datetime).

#### List Display Links
The following fields are clickable links to the detailed view:
- **ID**: Links to the detailed view of the field type.
- **Name**: Links to the detailed view of the field type.

#### Filtering
Admins can filter the list of field types based on:
- **Is Active**: Filter by active or inactive status.
- **Created At**: Filter by creation date.

#### Search Functionality
Admins can search for field types using:
- **Name**: Search by the field type’s name.
- **Description**: Search by the field type’s description.

#### Ordering
Records are ordered by:
- **Created At**: Descending order (newest first).

#### Read-Only Fields
The following field is marked as read-only in the detailed view:
- **Created At**: The timestamp when the field type was created.

---

## DynamicFieldAdmin

The `DynamicFieldAdmin` class provides an admin interface for managing `DynamicField` records within forms.

### Features

#### List Display
The list view for dynamic field records includes:
- **ID**: The unique identifier for the field (integer).
- **Name**: The name of the field (string).
- **Form**: The associated form (displayed as the form’s name).
- **Field Type**: The associated field type (displayed as the field type’s name).
- **Is Required**: A boolean indicating whether the field is mandatory (boolean).
- **Order**: The order of the field within the form (integer).

#### List Display Links
The following fields are clickable links to the detailed view:
- **ID**: Links to the detailed view of the field.
- **Name**: Links to the detailed view of the field.

#### Filtering
Admins can filter the list of fields based on:
- **Field Type**: Filter by the associated field type.
- **Is Required**: Filter by whether the field is required or not.
- **Form**: Filter by the associated form.

#### Search Functionality
Admins can search for fields using:
- **Name**: Search by the field’s name.
- **Form Name**: Search by the name of the associated form (via `form__name`).

#### Ordering
Records are ordered by:
- **Order**: Ascending order (fields sorted by their position in the form).
- **Name**: Ascending order (alphabetically within the same order).

#### Autocomplete Fields
The following fields use an autocomplete widget for easier selection:
- **Form**: Allows admins to quickly select a form from the database.
- **Field Type**: Allows admins to quickly select a field type from the database.

---

## FormSubmissionAdmin

The `FormSubmissionAdmin` class provides an admin interface for managing `FormSubmission` records.

### Features

#### List Display
The list view for form submission records includes:
- **ID**: The unique identifier for the submission (integer).
- **User**: The submitting user (displayed as the username, or empty if null).
- **Form**: The associated form (displayed as the form’s name).
- **Submitted At**: Timestamp when the submission was made (datetime).

#### List Display Links
The following fields are clickable links to the detailed view:
- **ID**: Links to the detailed view of the submission.
- **User**: Links to the detailed view of the submission.

#### Filtering
Admins can filter the list of submissions based on:
- **Submitted At**: Filter by submission date.
- **Form**: Filter by the associated form.

#### Search Functionality
Admins can search for submissions using:
- **Form Name**: Search by the name of the associated form (via `form__name`).

#### Ordering
Records are ordered by:
- **Submitted At**: Descending order (newest first).

#### Read-Only Fields
The following fields are marked as read-only in the detailed view:
- **User**: The submitting user (cannot be edited).
- **Submitted At**: The timestamp when the submission was made.
- **Submitted Data**: The JSON object containing the submitted field values.

#### Permissions
- **Add Permission**: Disabled (`has_add_permission` returns `False`), preventing admins from creating submissions manually.
- **Change Permission**: Disabled (`has_change_permission` returns `False`), preventing admins from modifying existing submissions.

#### Optimizations
- **List Select Related**: Uses `list_select_related` for `user` and `form` to optimize database queries in the list view.

----

# Settings

This section outlines the available settings for configuring the `dj-dynamic-form` package. You can customize these
settings in your Django project's `settings.py` file to tailor the behavior of the system monitor to your
needs.

## Example Settings

Below is an example configuration with default values:

```python
# Admin Settings
DYNAMIC_FORM_ADMIN_HAS_ADD_PERMISSION = True
DYNAMIC_FORM_ADMIN_HAS_CHANGE_PERMISSION = True
DYNAMIC_FORM_ADMIN_HAS_DELETE_PERMISSION = True
DYNAMIC_FORM_ADMIN_HAS_MODULE_PERMISSION = True
DYNAMIC_FORM_ADMIN_SITE_CLASS = "django.contrib.admin.sites.AdminSite"  # Default Django admin site

# Global API Settings
DYNAMIC_FORM_BASE_USER_THROTTLE_RATE = "30/minute"
DYNAMIC_FORM_STAFF_USER_THROTTLE_RATE = "100/minute"
DYNAMIC_FORM_API_ADMIN_PERMISSION_CLASS = "rest_framework.permissions.IsAdminUser"
DYNAMIC_FORM_USER_SERIALIZER_CLASS = "dynamic_form.api.serializers.user.UserSerializer"
# DYNAMIC_FORM_USER_SERIALIZER_FIELDS = [if not provided, gets USERNAME_FIELD and REQUIRED_FIELDS from user model]

# DynamicForm API Settings
DYNAMIC_FORM_API_DYNAMIC_FORM_SERIALIZER_CLASS = "dynamic_form.api.serializers.forms.DynamicFormSerializer"
DYNAMIC_FORM_API_DYNAMIC_FORM_ORDERING_FIELDS = ["created_at", "updated_at"]
DYNAMIC_FORM_API_DYNAMIC_FORM_SEARCH_FIELDS = ["name", "description"]
DYNAMIC_FORM_API_DYNAMIC_FORM_THROTTLE_CLASSES = "dynamic_form.api.throttlings.RoleBasedUserRateThrottle"
DYNAMIC_FORM_API_DYNAMIC_FORM_PAGINATION_CLASS = "dynamic_form.api.paginations.DefaultLimitOffSetPagination"
DYNAMIC_FORM_API_DYNAMIC_FORM_EXTRA_PERMISSION_CLASS = None
DYNAMIC_FORM_API_DYNAMIC_FORM_PARSER_CLASSES = [
    "rest_framework.parsers.JSONParser",
    "rest_framework.parsers.MultiPartParser",
    "rest_framework.parsers.FormParser",
]
DYNAMIC_FORM_API_DYNAMIC_FORM_FILTERSET_CLASS = None
DYNAMIC_FORM_API_DYNAMIC_FORM_ALLOW_LIST = True
DYNAMIC_FORM_API_DYNAMIC_FORM_ALLOW_RETRIEVE = True

# Admin DynamicForm API Settings
DYNAMIC_FORM_API_ADMIN_DYNAMIC_FORM_SERIALIZER_CLASS = "dynamic_form.api.serializers.DynamicFormSerializer"
DYNAMIC_FORM_API_ADMIN_DYNAMIC_FORM_ORDERING_FIELDS = ["name", "created_at", "updated_at"]
DYNAMIC_FORM_API_ADMIN_DYNAMIC_FORM_SEARCH_FIELDS = ["name", "description"]
DYNAMIC_FORM_API_ADMIN_DYNAMIC_FORM_THROTTLE_CLASSES = "dynamic_form.api.throttlings.RoleBasedUserRateThrottle"
DYNAMIC_FORM_API_ADMIN_DYNAMIC_FORM_PAGINATION_CLASS = "dynamic_form.api.paginations.DefaultLimitOffSetPagination"
DYNAMIC_FORM_API_ADMIN_DYNAMIC_FORM_EXTRA_PERMISSION_CLASS = None
DYNAMIC_FORM_API_ADMIN_DYNAMIC_FORM_PARSER_CLASSES = [
    "rest_framework.parsers.JSONParser",
    "rest_framework.parsers.MultiPartParser",
    "rest_framework.parsers.FormParser",
]
DYNAMIC_FORM_API_ADMIN_DYNAMIC_FORM_FILTERSET_CLASS = None
DYNAMIC_FORM_API_ADMIN_DYNAMIC_FORM_ALLOW_LIST = True
DYNAMIC_FORM_API_ADMIN_DYNAMIC_FORM_ALLOW_RETRIEVE = True
DYNAMIC_FORM_API_ADMIN_DYNAMIC_FORM_ALLOW_CREATE = True
DYNAMIC_FORM_API_ADMIN_DYNAMIC_FORM_ALLOW_UPDATE = True
DYNAMIC_FORM_API_ADMIN_DYNAMIC_FORM_ALLOW_DELETE = True

# DynamicField API Settings
DYNAMIC_FORM_API_DYNAMIC_FIELD_SERIALIZER_CLASS = "dynamic_form.api.serializers.field.DynamicFieldSerializer"
DYNAMIC_FORM_API_DYNAMIC_FIELD_ORDERING_FIELDS = ["name", "order"]
DYNAMIC_FORM_API_DYNAMIC_FIELD_SEARCH_FIELDS = ["name", "form__name"]
DYNAMIC_FORM_API_DYNAMIC_FIELD_THROTTLE_CLASSES = "dynamic_form.api.throttlings.RoleBasedUserRateThrottle"
DYNAMIC_FORM_API_DYNAMIC_FIELD_PAGINATION_CLASS = "dynamic_form.api.paginations.DefaultLimitOffSetPagination"
DYNAMIC_FORM_API_DYNAMIC_FIELD_EXTRA_PERMISSION_CLASS = None
DYNAMIC_FORM_API_DYNAMIC_FIELD_PARSER_CLASSES = [
    "rest_framework.parsers.JSONParser",
    "rest_framework.parsers.MultiPartParser",
    "rest_framework.parsers.FormParser",
]
DYNAMIC_FORM_API_DYNAMIC_FIELD_FILTERSET_CLASS = None
DYNAMIC_FORM_API_DYNAMIC_FIELD_ALLOW_LIST = True
DYNAMIC_FORM_API_DYNAMIC_FIELD_ALLOW_RETRIEVE = True

# Admin DynamicField API Settings
DYNAMIC_FORM_API_ADMIN_DYNAMIC_FIELD_SERIALIZER_CLASS = "dynamic_form.api.serializers.field.DynamicFieldSerializer"
DYNAMIC_FORM_API_ADMIN_DYNAMIC_FIELD_ORDERING_FIELDS = ["order"]
DYNAMIC_FORM_API_ADMIN_DYNAMIC_FIELD_SEARCH_FIELDS = ["name", "label"]
DYNAMIC_FORM_API_ADMIN_DYNAMIC_FIELD_THROTTLE_CLASSES = "dynamic_form.api.throttlings.RoleBasedUserRateThrottle"
DYNAMIC_FORM_API_ADMIN_DYNAMIC_FIELD_PAGINATION_CLASS = "dynamic_form.api.paginations.DefaultLimitOffSetPagination"
DYNAMIC_FORM_API_ADMIN_DYNAMIC_FIELD_EXTRA_PERMISSION_CLASS = None
DYNAMIC_FORM_API_ADMIN_DYNAMIC_FIELD_PARSER_CLASSES = [
    "rest_framework.parsers.JSONParser",
    "rest_framework.parsers.MultiPartParser",
    "rest_framework.parsers.FormParser",
]
DYNAMIC_FORM_API_ADMIN_DYNAMIC_FIELD_FILTERSET_CLASS = None
DYNAMIC_FORM_API_ADMIN_DYNAMIC_FIELD_ALLOW_LIST = True
DYNAMIC_FORM_API_ADMIN_DYNAMIC_FIELD_ALLOW_RETRIEVE = True
DYNAMIC_FORM_API_ADMIN_DYNAMIC_FIELD_ALLOW_CREATE = True
DYNAMIC_FORM_API_ADMIN_DYNAMIC_FIELD_ALLOW_UPDATE = True
DYNAMIC_FORM_API_ADMIN_DYNAMIC_FIELD_ALLOW_DELETE = True

# FieldType API Settings
DYNAMIC_FORM_API_FIELD_TYPE_SERIALIZER_CLASS = "dynamic_form.api.serializers.field_type.FieldTypeSerializer"
DYNAMIC_FORM_API_FIELD_TYPE_ORDERING_FIELDS = ["created_at", "updated_at"]
DYNAMIC_FORM_API_FIELD_TYPE_SEARCH_FIELDS = ["name", "label", "description"]
DYNAMIC_FORM_API_FIELD_TYPE_THROTTLE_CLASSES = "dynamic_form.api.throttlings.RoleBasedUserRateThrottle"
DYNAMIC_FORM_API_FIELD_TYPE_PAGINATION_CLASS = "dynamic_form.api.paginations.DefaultLimitOffSetPagination"
DYNAMIC_FORM_API_FIELD_