# create-user-model.mo

## Owner: [Sammy Teillet](https://github.com/samox)

## Context

* You have a Django project installed.
* You need to handle different types of users (for instance an Actor, a Producer, a Director) that will all inherit from the user, but will have different properties.
* You want to handle them from the admin.

## Prerequisites (\~45min)

* Have the project installed, [see this](https://github.com/bamlab/dev-standards/blob/master/backend/django/getting-started.mo.md)

## Situation

* You have a basic user model with a name.
* You want to create another type of user, a Mayor that has a City (the city is a foreign key to a City model).&#x20;
* You do not want to override the classic user model.
* You want to create a Mayor from the admin
* You want the newly created Mayor to be part of the Staff (Staff User can access the admin, but they are not SuperUser)

## Steps

### Add the Mayor model (5 min)

* In the models.py file, where the User is defined, create a new class that inherits the User

```python
# You should have the User in the same file, or from app.models import User
from django.db import models
from django.contrib.auth.models import User


class Mayor(User):
    city = models.ForeignKey('locations.city')

    class Meta:
        verbose_name = "Mayor"
```

* Create the migration file: `./manage.py makemigrations` or `docker-compose run django_container_name ./manage.py makemigrations`
* Run the migration: `./manage.py migrate` or `docker-compose run django_container_name ./manage.py migrate`

> **Check 1:** Run the show migration command to see the new one `./manage.py showmigrations`

### Create a Mayor from the admin (5 min)

* In the admin.py, where the User model is added `admin.register(User)`
* Add the following:

```python
from .models import Mayor
from django.contrib.auth.admin import UserAdmin

@admin.register(Mayor)
class MyMayorAdmin(UserAdmin):
    pass
```

> **Check 1:** You now see the Mayor in the admin. But all the forms (form to add a Mayor, form to change/update a Mayor) are the same as for the regular User.

### Override the admin form to add a Mayor (10 min)

* In the admin.py when you declared your MyMayorAdmin class, you can choose the fields you want to display in the form by overriding the `add_fieldsets` property. You can readme more about `add_fieldset` [here:](https://docs.djangoproject.com/en/1.11/topics/auth/customizing/#a-full-example)
* You need to know the fields you want to display. `username`, `password1` and `password2` are default fields of the "user admin add form"
* In our case:

```python
from .models import Mayor
from django.contrib.auth.admin import UserAdmin

class MyMayorAdmin(AuthUserAdmin):
    add_fieldsets = (
            ('User Profile', {'fields': ('username', 'city', 'password1', 'password2')}),
    )
```

> **Check 1:** You now see the city field in the "add new mayor" form.

### Give admin property to mayor user (10 min)

* You can manually set a user to be part of the staff, you can also override the save method of the AddForm so it changes the property is\_staff to True
* First create a form that inherits the AddUserForm and override the save method (see [overriding custom model method](https://docs.djangoproject.com/en/1.11/topics/db/models/#overriding-predefined-model-methods)):

```python
from django.contrib.auth.forms import UserCreationForm

class MyMayorCreationForm(UserCreationForm):

    class Meta(UserCreationForm.Meta):
        model = Mayor

    def save(self, commit=True):
        user = super().save(commit=False)
        user.is_staff = True
        if commit:
            user.save()
        return user
```

* Then use this form in the MyMayorAdmin class:

```python
@admin.register(Mayor)
class MyMayorAdmin(AuthUserAdmin):
    add_form = MyMayorCreationForm
```

> **Check 1**: When I create a mayor, I see that it is staff user in the detail view of the mayor.


---

# 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://bamtech.gitbook.io/dev-standards/backend/django/create-user-model.mo.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.
