Why django admin is not reading the __str__ method?

555 Views Asked by At

I'm trying to add a str method in my models.py file to my administrative page show me the objects I've register with their own name and not like a 'UserObject(1)'

But when I add this method that's what is happening:

AttributeError at /admin/crud_app/user/ 'User' object has no attribute 'first_name'

models.py ->

from django.db import models


class User(models.Model):
    """
    A normal class that represents an User object, the attributes are those bellow:
    """
    first_name = models.CharField(name="First Name", max_length=30)
    last_name = models.CharField(name="Last Name", max_length=30)
    cpf = models.CharField(name="CPF", max_length=30)
    age = models.IntegerField(name="Age")
    email = models.EmailField(name="email", max_length=30)

    def __str__(self):
        return self.first_name
    

admin.py ->

from django.contrib import admin
from .models import User

admin.site.register(User)

I try to add the str method and I'm was expecting to recive the name that I give to my object registered instead of 'Name object(1)'

2

There are 2 best solutions below

17
On

You should define it in f-strings to take care of None values so that if it is None so it will not raise error.

class User(models.Model):
    """
    A normal class that represents an User object, the attributes are those bellow:
    """
    first_name = models.CharField(name="First Name", max_length=30)
    last_name = models.CharField(name="Last Name", max_length=30)
    cpf = models.CharField(name="CPF", max_length=30)
    age = models.IntegerField(name="Age")
    email = models.EmailField(name="email", max_length=30)

    def __str__(self):
        return f"{self.first_name}"

Also hard refresh through ctrl+f5 and restart server in another port using python manage.py runserver 5000.

Edit

After looking at your GitHub repo, I observed the issue is with naming the model as User which is an in-built model in Django in django.contrib.auth so kindly change it to CustomUser and also the problem arises with fields first_name and last_name as these are also in User model so kindly try below model:

from django.db import models


class CustomUser(models.Model):
    """
    A normal class that represents a User object, the attributes are those bellow:
    """
    f_name = models.CharField(
        verbose_name="First Name", max_length=30, default="Test")
    l_name = models.CharField(
        verbose_name="Last Name", max_length=30, default='Test')
    cpf = models.CharField(verbose_name="CPF", max_length=15)
    age = models.IntegerField(verbose_name="Age")
    email = models.EmailField(verbose_name="email", max_length=30)

    def __str__(self):
        return f"{self.f_name}"

Then run both the migration commands (makemigrations and migrate).

admin.py

from django.contrib import admin
from .models import CustomUser


@admin.register(CustomUser)
class CustomUserAdmin(admin.ModelAdmin):
    list_display = ['id', 'f_name', 'l_name', 'cpf', 'age', 'email']

urls.py

from django.urls import path
from crud_app.views import update_user, check_user, delete_user, register_user, menu

urlpatterns = [
    path('', menu),
    path("check_user/", check_user, name="check_user.html"),
    path("register_user/", register_user, name="register_user.html"),
    path("update_user/", update_user, name="update_user.html"),
    path("delete_user/", delete_user, name="delete_user.html")
]

Then you can change the fields' name in templates by yourself.

3
On

You need to correct verbose_name instead of name of model fields like this.

class User(models.Model):
    """
    A normal class that represents an User object, the attributes are those bellow:
    """
    first_name = models.CharField(verbose_name="First Name", max_length=30)
    last_name = models.CharField(verbose_name="Last Name", max_length=30)
    cpf = models.CharField(verbose_name="CPF", max_length=30)
    age = models.IntegerField(verbose_name="Age")
    email = models.EmailField(verbose_name="email", max_length=30)

    def __str__(self):
        return self.first_name