How is my list_display and list_editable clashing?
Question:
When I started building this project, it went pretty smoothly. But when I reached the admin, list_display and list_editable clashed:
admin.py Code:
from django.contrib import admin
from .models import Article, Author
# Register your models here.
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ['title', 'main_txt', 'date_of_publication']
list_editable = ['title', 'main_txt']
def __str__(self):
return self.title
@admin.register(Author)
class AuthorAdmin(admin.ModelAdmin):
list_display = ['first_name', 'last_name', 'join_date', 'email']
def __str__(self):
return f"{self.first_name} {self.last_name[0]}"
models.py:
from django.db import models
# Create your models here.
class Author(models.Model):
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
date_of_birth = models.DateField()
email = models.CharField(max_length=300)
phone_num = models.CharField(max_length=15)
join_date = models.DateField()
participated_art = models.ManyToManyField('Article', blank=True)
class Article(models.Model):
title = models.CharField(max_length=500)
date_of_publication = models.DateField()
creaters = models.ManyToManyField('Author', blank=False)
main_txt = models.TextField()
notes = models.TextField()
Error Code:
Exception in thread Django-main-thread:
Traceback (most recent call last):
File "C:UsersZhiyueAppDataLocalProgramsPythonPython39libthreading.py", line 980, in _bootstrap_inner
self.run()
File "C:UsersZhiyueAppDataLocalProgramsPythonPython39libthreading.py", line 917, in run
self._target(*self._args, **self._kwargs)
File "C:UsersZhiyuePycharmProjectsdjangoProject1venvlibsite-packagesdjangoutilsautoreload.py", line 64, in wrapper
fn(*args, **kwargs)
File "C:UsersZhiyuePycharmProjectsdjangoProject1venvlibsite-packagesdjangocoremanagementcommandsrunserver.py", line 134, in inner_run
self.check(display_num_errors=True)
File "C:UsersZhiyuePycharmProjectsdjangoProject1venvlibsite-packagesdjangocoremanagementbase.py", line 546, in check
raise SystemCheckError(msg)
django.core.management.base.SystemCheckError: SystemCheckError: System check identified some issues:
ERRORS:
<class 'CodeJangoHome.admin.ArticleAdmin'>: (admin.E124) The value of 'list_editable[0]' refers to the first field in 'list_display' ('title'), which cannot be used unless 'list_display_links' is set.
System check identified 1 issue (0 silenced).
After I read the error, as shown above, I tried adding list_display_links = ['title', 'main_txt']
into the code:
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ['title', 'main_txt', 'date_of_publication']
list_editable = ['title', 'main_txt']
def __str__(self):
return self.title
But it didn’t work out the way it was supposed to. I got another error, that was between list_display_links
and list_editable
:
Exception in thread django-main-thread:
Traceback (most recent call last):
File "C:UsersZhiyueAppDataLocalProgramsPythonPython39libthreading.py", line 980, in _bootstrap_inner
self.run()
File "C:UsersZhiyueAppDataLocalProgramsPythonPython39libthreading.py", line 917, in run
self._target(*self._args, **self._kwargs)
File "C:UsersZhiyuePycharmProjectsdjangoProject1venvlibsite-packagesdjangoutilsautoreload.py", line 64, in wrapper
fn(*args, **kwargs)
File "C:UsersZhiyuePycharmProjectsdjangoProject1venvlibsite-packagesdjangocoremanagementcommandsrunserver.py", line 134, in inner_run
self.check(display_num_errors=True)
File "C:UsersZhiyuePycharmProjectsdjangoProject1venvlibsite-packagesdjangocoremanagementbase.py", line 546, in check
raise SystemCheckError(msg)
django.core.management.base.SystemCheckError: SystemCheckError: System check identified some issues:
ERRORS:
<class 'CodeJangoHome.admin.ArticleAdmin'>: (admin.E123) The value of 'title' cannot be in both 'list_editable' and 'list_display_links'.
<class 'CodeJangoHome.admin.ArticleAdmin'>: (admin.E123) The value of 'main_txt' cannot be in both 'list_editable' and 'list_display_links'.
System check identified 2 issues (0 silenced).
So, with list_display, list_editable, and list_display_links, I have a problem fitting them into the code in admin.py.I don’t exactly know how to use them so a bit of help would be useful.
Answers:
According to django documentation. Here
- Any field in
list_editable
must also be in list_display
. You can’t edit a field that’s not displayed!
- The same field can’t be listed in both
list_editable
and list_display_links
– a field can’t be both a form and a link.
So in list_display_links
you should have a different field from those in list_editable
Django automatically set the first column of list_display
as a link to the change form.
You can either add another column (recommended), like
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ['__str__', 'title', 'main_txt', 'date_of_publication']
list_editable = ['title', 'main_txt']
def __str__(self):
return self.title
or explicitly set list_display_links
to None
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ['title', 'main_txt', 'date_of_publication']
list_editable = ['title', 'main_txt']
list_display_links = None
def __str__(self):
return self.title
EDIT:
It is not required to put __str__
in list_display
. It is just the first column of list_display
that makes it special: Django automatically convert it to a link, if not specified.
PS: What can be used in list_display
?
According to Django’s docs,
- A field of model.
- A callable.
- A string representing a ModelAdmin attribute.
- A string representing a model attribute.
Example list_display
s:
@admin.display(descriptor='Title')
def upper_case_title(obj):
return obj.title.upper()
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ['__str__', 'title', 'main_txt', 'date_of_publication']
# 1. list_display = ['id', 'title', 'main_txt', 'date_of_publication']
# 2. list_display = ['article_title', 'title', 'main_txt', 'date_of_publication']
# 3. list_display = ['__str__', 'title', 'main_txt', 'date_of_publication']
# 4. list_display = ['id_title', 'title', 'main_txt', 'date_of_publication']
list_editable = ['title', 'main_txt']
def __str__(self):
return self.title
To implement 4. you need to modify model definition
#models.py
from django.contrib import admin
from django.db import models
class Article(models.Model):
title = models.CharField(max_length=500)
date_of_publication = models.DateField()
creaters = models.ManyToManyField('Author', blank=False)
main_txt = models.TextField()
notes = models.TextField()
@admin.display(descriptor='Title')
def id_title(self):
return f'{self.id}. {self.title}'
Again, I am just giving examples, you are not required to code exactly as above.
You got the error below:
ERRORS:
<class ‘CodeJangoHome.admin.ArticleAdmin’>: (admin.E124) The
value of ‘list_editable[0]’ refers to the first field in
‘list_display’ (‘title’), which cannot be used unless
‘list_display_links’ is set.
Because by default, the 1st column "title" is link unless you set list_display_links and you tried to make the link editable by assigning it to list_editable which is impossible to make the link editable:
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
# ↓ Link
list_display = ['title', 'main_txt', 'date_of_publication']
list_editable = ['title', 'main_txt']
# ↑ Tries to make the link editable but impossible
def __str__(self):
return self.title
And, you got the errors below:
ERRORS:
<class ‘CodeJangoHome.admin.ArticleAdmin’>:
(admin.E123) The value of ‘title’ cannot be in both ‘list_editable’
and ‘list_display_links’.
<class ‘CodeJangoHome.admin.ArticleAdmin’>: (admin.E123) The
value of ‘main_txt’ cannot be in both ‘list_editable’ and
‘list_display_links’.
Because you assigned 'title'
and 'main_txt'
to both list_editable
and list_display_links
as shown below which is impossible that a column is both link and editable:
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ['title', 'main_txt', 'date_of_publication']
list_editable = ['title', 'main_txt']
# ↑Here↓ ↑Here↓ Impossible
list_display_links = ['title', 'main_txt']
def __str__(self):
return self.title
So to solve your errors, add list_display_links = ['date_of_publication']
as shown below to disable link for the 1st column "title" and to enable link for the 3rd column "date_of_publication" as shown below:
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ['title', 'main_txt', 'date_of_publication']
list_editable = ['title', 'main_txt']
list_display_links = ['date_of_publication'] # Here
def __str__(self):
return self.title
Or, add list_display_links = None
to disable link for the 1st column "title" as shown below:
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ['title', 'main_txt', 'date_of_publication']
list_editable = ['title', 'main_txt']
list_display_links = None # Here
def __str__(self):
return self.title
When I started building this project, it went pretty smoothly. But when I reached the admin, list_display and list_editable clashed:
admin.py Code:
from django.contrib import admin
from .models import Article, Author
# Register your models here.
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ['title', 'main_txt', 'date_of_publication']
list_editable = ['title', 'main_txt']
def __str__(self):
return self.title
@admin.register(Author)
class AuthorAdmin(admin.ModelAdmin):
list_display = ['first_name', 'last_name', 'join_date', 'email']
def __str__(self):
return f"{self.first_name} {self.last_name[0]}"
models.py:
from django.db import models
# Create your models here.
class Author(models.Model):
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
date_of_birth = models.DateField()
email = models.CharField(max_length=300)
phone_num = models.CharField(max_length=15)
join_date = models.DateField()
participated_art = models.ManyToManyField('Article', blank=True)
class Article(models.Model):
title = models.CharField(max_length=500)
date_of_publication = models.DateField()
creaters = models.ManyToManyField('Author', blank=False)
main_txt = models.TextField()
notes = models.TextField()
Error Code:
Exception in thread Django-main-thread:
Traceback (most recent call last):
File "C:UsersZhiyueAppDataLocalProgramsPythonPython39libthreading.py", line 980, in _bootstrap_inner
self.run()
File "C:UsersZhiyueAppDataLocalProgramsPythonPython39libthreading.py", line 917, in run
self._target(*self._args, **self._kwargs)
File "C:UsersZhiyuePycharmProjectsdjangoProject1venvlibsite-packagesdjangoutilsautoreload.py", line 64, in wrapper
fn(*args, **kwargs)
File "C:UsersZhiyuePycharmProjectsdjangoProject1venvlibsite-packagesdjangocoremanagementcommandsrunserver.py", line 134, in inner_run
self.check(display_num_errors=True)
File "C:UsersZhiyuePycharmProjectsdjangoProject1venvlibsite-packagesdjangocoremanagementbase.py", line 546, in check
raise SystemCheckError(msg)
django.core.management.base.SystemCheckError: SystemCheckError: System check identified some issues:
ERRORS:
<class 'CodeJangoHome.admin.ArticleAdmin'>: (admin.E124) The value of 'list_editable[0]' refers to the first field in 'list_display' ('title'), which cannot be used unless 'list_display_links' is set.
System check identified 1 issue (0 silenced).
After I read the error, as shown above, I tried adding list_display_links = ['title', 'main_txt']
into the code:
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ['title', 'main_txt', 'date_of_publication']
list_editable = ['title', 'main_txt']
def __str__(self):
return self.title
But it didn’t work out the way it was supposed to. I got another error, that was between list_display_links
and list_editable
:
Exception in thread django-main-thread:
Traceback (most recent call last):
File "C:UsersZhiyueAppDataLocalProgramsPythonPython39libthreading.py", line 980, in _bootstrap_inner
self.run()
File "C:UsersZhiyueAppDataLocalProgramsPythonPython39libthreading.py", line 917, in run
self._target(*self._args, **self._kwargs)
File "C:UsersZhiyuePycharmProjectsdjangoProject1venvlibsite-packagesdjangoutilsautoreload.py", line 64, in wrapper
fn(*args, **kwargs)
File "C:UsersZhiyuePycharmProjectsdjangoProject1venvlibsite-packagesdjangocoremanagementcommandsrunserver.py", line 134, in inner_run
self.check(display_num_errors=True)
File "C:UsersZhiyuePycharmProjectsdjangoProject1venvlibsite-packagesdjangocoremanagementbase.py", line 546, in check
raise SystemCheckError(msg)
django.core.management.base.SystemCheckError: SystemCheckError: System check identified some issues:
ERRORS:
<class 'CodeJangoHome.admin.ArticleAdmin'>: (admin.E123) The value of 'title' cannot be in both 'list_editable' and 'list_display_links'.
<class 'CodeJangoHome.admin.ArticleAdmin'>: (admin.E123) The value of 'main_txt' cannot be in both 'list_editable' and 'list_display_links'.
System check identified 2 issues (0 silenced).
So, with list_display, list_editable, and list_display_links, I have a problem fitting them into the code in admin.py.I don’t exactly know how to use them so a bit of help would be useful.
According to django documentation. Here
- Any field in
list_editable
must also be inlist_display
. You can’t edit a field that’s not displayed!- The same field can’t be listed in both
list_editable
andlist_display_links
– a field can’t be both a form and a link.
So in list_display_links
you should have a different field from those in list_editable
Django automatically set the first column of list_display
as a link to the change form.
You can either add another column (recommended), like
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ['__str__', 'title', 'main_txt', 'date_of_publication']
list_editable = ['title', 'main_txt']
def __str__(self):
return self.title
or explicitly set list_display_links
to None
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ['title', 'main_txt', 'date_of_publication']
list_editable = ['title', 'main_txt']
list_display_links = None
def __str__(self):
return self.title
EDIT:
It is not required to put __str__
in list_display
. It is just the first column of list_display
that makes it special: Django automatically convert it to a link, if not specified.
PS: What can be used in list_display
?
According to Django’s docs,
- A field of model.
- A callable.
- A string representing a ModelAdmin attribute.
- A string representing a model attribute.
Example list_display
s:
@admin.display(descriptor='Title')
def upper_case_title(obj):
return obj.title.upper()
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ['__str__', 'title', 'main_txt', 'date_of_publication']
# 1. list_display = ['id', 'title', 'main_txt', 'date_of_publication']
# 2. list_display = ['article_title', 'title', 'main_txt', 'date_of_publication']
# 3. list_display = ['__str__', 'title', 'main_txt', 'date_of_publication']
# 4. list_display = ['id_title', 'title', 'main_txt', 'date_of_publication']
list_editable = ['title', 'main_txt']
def __str__(self):
return self.title
To implement 4. you need to modify model definition
#models.py
from django.contrib import admin
from django.db import models
class Article(models.Model):
title = models.CharField(max_length=500)
date_of_publication = models.DateField()
creaters = models.ManyToManyField('Author', blank=False)
main_txt = models.TextField()
notes = models.TextField()
@admin.display(descriptor='Title')
def id_title(self):
return f'{self.id}. {self.title}'
Again, I am just giving examples, you are not required to code exactly as above.
You got the error below:
ERRORS:
<class ‘CodeJangoHome.admin.ArticleAdmin’>: (admin.E124) The
value of ‘list_editable[0]’ refers to the first field in
‘list_display’ (‘title’), which cannot be used unless
‘list_display_links’ is set.
Because by default, the 1st column "title" is link unless you set list_display_links and you tried to make the link editable by assigning it to list_editable which is impossible to make the link editable:
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
# ↓ Link
list_display = ['title', 'main_txt', 'date_of_publication']
list_editable = ['title', 'main_txt']
# ↑ Tries to make the link editable but impossible
def __str__(self):
return self.title
And, you got the errors below:
ERRORS:
<class ‘CodeJangoHome.admin.ArticleAdmin’>:
(admin.E123) The value of ‘title’ cannot be in both ‘list_editable’
and ‘list_display_links’.
<class ‘CodeJangoHome.admin.ArticleAdmin’>: (admin.E123) The
value of ‘main_txt’ cannot be in both ‘list_editable’ and
‘list_display_links’.
Because you assigned 'title'
and 'main_txt'
to both list_editable
and list_display_links
as shown below which is impossible that a column is both link and editable:
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ['title', 'main_txt', 'date_of_publication']
list_editable = ['title', 'main_txt']
# ↑Here↓ ↑Here↓ Impossible
list_display_links = ['title', 'main_txt']
def __str__(self):
return self.title
So to solve your errors, add list_display_links = ['date_of_publication']
as shown below to disable link for the 1st column "title" and to enable link for the 3rd column "date_of_publication" as shown below:
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ['title', 'main_txt', 'date_of_publication']
list_editable = ['title', 'main_txt']
list_display_links = ['date_of_publication'] # Here
def __str__(self):
return self.title
Or, add list_display_links = None
to disable link for the 1st column "title" as shown below:
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ['title', 'main_txt', 'date_of_publication']
list_editable = ['title', 'main_txt']
list_display_links = None # Here
def __str__(self):
return self.title