---
title: "Naming"
space: "Framework Git"
url: "https://docs.frappe.io/framework-git/doctypes/naming"
updated: "2026-10-11"
---

Every document has a unique primary key stored in its `name` field. The **naming rule** of a DocType decides how that `name` is generated when a document is inserted. You configure it through the `autoname` property (or the friendlier `naming_rule` selector in the DocType form).

Naming is resolved in `frappe/model/naming.py` (`set_new_name`). The rules below are tried based on the `autoname` value.

## Naming options

### By a field value: `field:`

Use the value of another field as the name.

```text
field:email
```

The field must be filled, or Frappe throws "`<label>` is required". A unique index is created on that field automatically.

### By a naming series: `naming_series:`

Generate sequential names from a prefix with a counter. The document needs a `naming_series` field (usually a Select) and the running number comes from the `tabSeries` table.

```text
naming_series:
```

A series key like `SINV-.YYYY.-.#####` produces `SINV-2024-00001`, `SINV-2024-00002`, … The special parts:

| Part              | Expands to                                    |
| ----------------- | --------------------------------------------- |
| `.#####`          | Zero-padded counter (number of `#` = digits). |
| `.YYYY.` / `.YY.` | 4- or 2-digit year.                           |
| `.MM.` / `.DD.`   | Month / day.                                  |
| `.WW.`            | ISO week number.                              |
| `.JJJ.`           | Day of year.                                  |
| `.timestamp.`     | Current timestamp.                            |

Parts are separated by dots. The text before the counter (e.g. `SINV-2024-`) is stored as the prefix whose counter lives in `tabSeries`.

### Expression: `format:`

Build the name from a template mixing literal text, date parts and field values in braces.

```text
format:TASK-{customer}-{####}
```

`{customer}` is replaced by the document's `customer` value and `{####}` by a counter. You can also reference date parts like `{YYYY}`.

### Prompt

Ask the user to type a name when creating the document.

```text
prompt
```

The entered value arrives in `__newname` and is validated before being set as `name`.

### Hash (random)

Assign a random hash. This is the default fallback when no rule is set.

```text
hash
```

### Autoincrement

Use a database sequence to produce monotonically increasing integer names. Set this at creation time; it **cannot be changed** afterwards.

```text
autoincrement
```

Internally this calls `frappe.db.get_next_sequence_val(doctype)`.

### UUID

Assign a UUID (v7) as the name.

```text
UUID
```

## Naming from the controller

If you need full control, define an `autoname` method on the controller. It runs only if no name has been set by the rules above.

```python
from frappe.model.document import Document
from frappe.model.naming import make_autoname

class Task(Document):
    def autoname(self):
        self.name = make_autoname(f"TASK-{self.project}-.#####")
```

`make_autoname(key, doctype, doc)` accepts the same series syntax described above and also `"hash"`.

## Document Naming Rule

**Document Naming Rule** is a DocType, so you can add naming rules for any DocType at runtime without touching code. Each rule names documents of one `document_type` using a `prefix` and a counter `prefix_digits` wide.

A rule with prefix `todo-high-` and `prefix_digits` 3 produces `todo-high-001`, `todo-high-002`, and so on. The prefix runs through the same placeholder parser, so `todo-.YYYY.-` resolves date parts too.

Each rule has:

| Field           | Purpose                                                            |
| --------------- | ------------------------------------------------------------------ |
| `document_type` | The DocType the rule names.                                        |
| `priority`      | Rules are tried highest priority first.                            |
| `conditions`    | Optional filters; the rule only applies when the document matches. |
| `prefix`        | Text prepended before the counter.                                 |
| `prefix_digits` | Width of the zero-padded counter.                                  |
| `disabled`      | Skip the rule when checked.                                        |

You can define several rules for one DocType. `set_naming_from_document_naming_rule` loads the enabled rules ordered by `priority desc` and applies them until one sets `name`, so the first matching rule wins.

## Resolution order

When a document is inserted, `set_new_name` applies the first matching rule:

1. Run the controller's `before_naming` hook, if defined.
2. If `autoname` is `autoincrement`, use the DB sequence (returns immediately).
3. If `autoname` is `UUID`, generate a UUID (returns immediately).
4. If amending a cancelled doc, append an amendment suffix.
5. For Single DocTypes, the name is always the DocType name.
6. Apply any matching **Document Naming Rule** (a runtime-configurable DocType).
7. Call the controller's `autoname()` method if defined.
8. Apply the `autoname` option (`field:`, `naming_series:`, `format:`, `prompt`, expression).
9. Fall back to a random `hash`.

## Renaming

If the DocType has `allow_rename` enabled, a document can be renamed (which updates the primary key and all references):

```python
doc = frappe.get_doc("Task", "TASK-0001")
doc.rename("TASK-0001-A", merge=False)
```

## See also

- [Fields](/framework-git/doctypes/fields): defining the field used by `field:` naming.
- [Single DocTypes](/framework-git/doctypes/single-doctypes): why singles are named after their DocType.
