# Table

{% hint style="info" %}
For this panel content, the panel frame url\_name must be **frame\_table**, and it must have a url\_action\_name for the Automail URL controller to find the panel content.
{% endhint %}

Below is an example configuration of a panel using the **Table** module:

```python
{
    "title": "Default Lead-Time",
    "width": 12,
    "full_row": True,
    "url_name": "frame_table",
    "url_action_name": "table_defaultleadtimetracker",
    "content": {
        "view": api_views.Table,
        "view_params": {
            "model": custom_models.DefaultLeadTimeTracker,
            "order_by": "id",
            "init_max_rows_threshold": 20000,
            "table_settings": {
                "options": {
                    "hide_id_column": True,
                },
                "permissions": {
                    "read": {
                        "allowed": True,
                        "allowed_user_groups": [],
                        "allowed_users": [],
                    },
                    "update": {
                        "allowed": False,
                        "allowed_user_groups": [],
                        "allowed_users": [],
                    },
                    "insert": {
                        "allowed": False,
                        "allowed_user_groups": [],
                        "allowed_users": [],
                    },
                    "delete": {
                        "allowed": False,
                        "allowed_user_groups": [],
                        "allowed_users": [],
                    },
                },
            },
            "field_definitions": {
                "supplier__name": {
                    "source_include_filters": {
                        "is_t2": True
                    }
                },
                "season__search_reference_suggestion_text": {},
                "web_number": {},
                "update_timestamp": {"read_only": True},
                "user_id": {"read_only": True},
            },
            "include_filters_extra": {
                "report_category": "Delivery Report",
            },
        },
    },
}
```

The **view\_params** are:

* **model** the model this table is based on
* **order\_by** the model field (str) or fields (list) to order the table by when loading (by default ascending alphanumeric order, for descending order use the prefix "-" (e.g. "-id"))
* **is\_empty** sets whether the table should be empty by default until the user clicks the Search button (must have a selectpickers section on top of the page)
* **init\_max\_rows\_threshold** the maximum number of rows that will be displayed without the user clicking the Search button
* **table\_settings** the table-level configuration

Create an uploadfile\_\_.py to upload the table in database

```python
try:
    from _init import *
except ImportError:
    from configurations.workflow_env import *
from polygon.apps.app_flows.controller import process_uploadfiles


def process_uploadfiles_monitor_coc():
    process_uploadfiles(
        **{
            "model": custom_models.Monitor,
            "table_settings": {
                "options": {
                    "hide_id_column": True,
                    "fixed_write_fields": {
                        "survey": "Chain of Custody Management",
                    },
                },
                "uploading_config": {
                    "extract": {
                        "sheet_name": 0,
                    },
                    "load": {
                        "do_bulk_insert": True,
                        "method": {
                            "function": "upsert",
                            "params": {
                                "unique_together": True,
                                "key_fields": [
                                    "season",
                                    "supplier_id",
                                    "surveygroup_id",
                                ],
                            },
                        },
                    },
                },
            },
            "field_definitions": {
                "season": {"allow_empty": False},
                "surveygroup__name": {
                    "allow_empty": False,
                    "source_include_filters": {"survey": "Chain of Custody Management"},
                },
                "supplier__name": {
                    "allow_empty": False,
                    "threshold_level": "strict",
                    # "label_alternatives": ["Select Supplier"],
                },
                "supplier__suppliergroup__name": {
                    "threshold_level": "strict",
                },
                "survey_contact_email": {
                    "allow_empty": False,
                    "internal_type": "EmailField",
                    "threshold_level": "strict",
                },
            },
        }
    )


if __name__ == "__main__":
    write_to_file(log_file_path, "process_uploadfiles_monitor_coc")
    monitoring(process_uploadfiles_monitor_coc)
    write_to_file(log_file_path, "completed")

```

For each column name in "field\_definition",  you can set up additional settings for the table

```python

"field_definitions": {
    "survey": {
        "source": custom_models.KEY_MATERIAL_SURVEYS,
    },
    "question": {
        "width": 300,
        "validations": [
            {
                "name": "custom",
                "params": {
                    "function": custom_functions.validate_question_exist,
                    "message": "The question(s) are not valid for the corresponding survey. <br>",
                },
            }
        ],
    },
    "answer": {
        "width": 300,
    },
    "survey_contact_email": {
        "transformations": [
            "lower",
            {
                "name": "sort_alphabetical_split_by_separator",
                "params": {
                    "separator": ",",
                },
            },
        ],
        "validations": [
            {
                "name": "custom",
                "params": {
                    "function": custom_functions.validate_contact_email,
                    "message": "Only valid email addresses allowed for",
                },
            },
        ],
    },
    "update_timestamp": {"read_only": True},
    "user_id": {"read_only": True},
},
```

* **source** the value in each row for the column should be in the field of the list you provided
* **width** set up the initial width for the column
* **validations** will validate the input value in the column and provide the message showing when the validation fails. You can set up the custom function in f**unction.py** like this&#x20;

<pre class="language-python"><code class="lang-python"><strong>def validate_question_exist(df, filtered_df):
</strong>    def apply_validation(row):
        questions = list(
            custom_models.MonitorQuestionAnswer.objects.filter(
                question_category=row["survey"]
            )
            .values_list("question", flat=True)
            .distinct()
        )
        return row["question"] in questions

    df["is_valid_flag"] = filtered_df.apply(apply_validation, args=(), axis=1)
    return df
</code></pre>

* **transformations** can transform the initial input value in the table to a specific value based on the custom function or a set-up function.

Process\_upload\_file function parameters are:

* **model** the model this table is based on
* **table\_settings** can set up the configurations in the table
* **field\_definitions** determine the column and its constraints, and you can also provide the column label alternatives to catch the column in the table.

<figure><img src="/files/7Q8dLdN1hu8UJmo6UvTf" alt=""><figcaption></figcaption></figure>

After dropping the Excel file in the upload box, you can run the uploadfile\_\_.py to load the table in the database.

You can also set the uploadfile\_\_.py as a Dag. Check the dag part

{% content-ref url="/pages/1G9eExC3R5k4vlru0SUq" %}
[Dags](/automail/configurations/workflow-configuration/dags.md)
{% endcontent-ref %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.lineverge.com/automail/configurations/ui-configuration/site/panels/table.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
