Django Error (admin.E106) ModelInline must have a 'model' attribute - django

Was just following the tutorials from Django documentation.
In Writing your first Django app, part 7, the tutorial was adding the Choice section when a user is adding a Question.
In the documentation, the code seems to work fine, but in my system, for some reason it isn't working. Please tell me where I got it wrong.
code:
from django.contrib import admin
from .models import Choice, Question
# Register your models here.
class ChoiceInline(admin.TabularInline):
model: Choice
extra: 3
class QuestionAdmin(admin.ModelAdmin):
# fields = ['pub_date', 'question_text']
fieldsets = [
(None, {'fields': ['question_text']}),
('Date Information', {'fields': ['pub_date'],
'classes':['collapse']}),
]
inlines = [ChoiceInline]
admin.site.register(Question, QuestionAdmin)
Error:
<class 'polls.admin.QuestionAdmin'>: (admin.E105) 'polls.admin.ChoiceInline' must have a 'model' attribute.

Related

Django Custom User Model - Form Tuple Problems

I'm creating a Custom User Model, based on AbstractUser, which has several extra fields added. I've read through the documentation and assorted examples, but I'm having a couple of frustrating (and probably simple) issues
I'm adding some extra fields to the user and the admin, for later group validation. I'm trying to add the custom fields to the Custom UserCreationForm and UserChangeForm, and I'm using Class Meta: to try and add my new fields in while including the existing ones using the form
class CustomUserCreationForm(UserCreationForm):
class Meta(UserCreationForm):
model = CustomUser
fields = UserCreationForm.Meta.fields + ('character_name' ,'ritual_points', 'contribute_points',)
class CustomUserChangeForm(UserChangeForm):
class Meta(UserChangeForm):
model = CustomUser
fields = UserChangeForm.Meta.fields + ('character_name', 'ritual_points', 'contribute_points',)
Which according to all the examples I've seen should just work. However, every time i try and make the migrations, it throws a strop
TypeError: Can't convert 'tuple' object to str implicitly
Everything I've read suggests this should work without any issues.
EDIT The plot thickens. I applied an earlier answer to change the () to a list [] to convert he fields to list, and it came back with a different answer:
TypeError: Can't convert 'list' object to str implicitly
Interestingly, this is working without any problems for the CustomUserCreationForm (which gives a different error if I try and change the () to [], but CustomUserChangeForm is throwing the error.
just convert fields to list instead of tuple. This will solve your problem.
fields = UserChangeForm.Meta.fields + ['character_name', 'ritual_points', 'contribute_points',]
The problem is the UserChangeForm.Meta.fields holds the value '__all__' while UserCreationForm.Meta.fields is in fact a tuple.
>>> from django.contrib.auth.forms import UserCreationForm, UserChangeForm
>>> UserChangeForm.Meta.fields
'__all__'
>>> UserCreationForm.Meta.fields
('username',)
In the documentation it's mentioned that we also need to set the values of fieldsetsand add_fieldsets. See the note at the bottom of this paragraph in the documentation.
I solved the issues you are facing by only extending the creation form and setting the values of fieldsetsand add_fieldsets like so:
class CustomUserAdmin(UserAdmin):
add_form = CustomUserCreationForm
model = User
fieldsets = UserAdmin.fieldsets + (
(None, {'fields': ('extra_fields',)}),
)
add_fieldsets = UserAdmin.add_fieldsets + (
(None, {'fields': ('extra_fields',)}),
)
This should give you what you asked for. My theory is that due to the fact that the change form already uses '__all__' fields we don't need to alter it, only add fields to the fieldsets.

Migrating from Django 1.11 to 2.1: There are duplicate field(s) in 'fieldsets[2][1]'

I'm currently migrating my Django 1.11 app to Django 2.1. I have a custom user model:
from authtools.models import AbstractEmailUser, UserManager
from django.db import models
from django.utils.translation import ugettext_lazy as _
from model_utils.fields import AutoLastModifiedField
from model_utils.models import SoftDeletableModel
from core.behaviors import UniversallyUniqueIdentifiable
class User(
UniversallyUniqueIdentifiable,
SoftDeletableModel,
AbstractEmailUser
):
"""
User should generally not be deleted, but rather is_removed should just
be set to true. The delete() method is overwritten in the
SoftDeletableModel.
Also add a uuid field to avoid displaying the sequential primary key.
"""
name = models.CharField(_('name'), max_length=255, blank=True)
modified = AutoLastModifiedField(_('modified'))
objects = UserManager()
And a custom admin:
from authtools.admin import (BASE_FIELDS, SIMPLE_PERMISSION_FIELDS,
NamedUserAdmin)
from django.contrib import admin
from .models import User
def verified(obj):
email = obj.emailaddress_set.filter(primary=True)
if email.exists():
return email[0].verified
return False
verified.boolean = True
#admin.register(User)
class SoftDeletableNamedUserAdmin(NamedUserAdmin):
"""
Overwrite the fields of the NamedUserAdmin to add is_removed.
"""
date_hierarchy = "date_joined"
list_display = (
'email',
'name',
verified,
'is_active',
'is_removed',
)
search_fields = ["email", "name"]
readonly_fields = ("date_joined", "modified")
fieldsets = (
BASE_FIELDS,
SIMPLE_PERMISSION_FIELDS,
("Contact information", {
"fields": (
("email", "name"),
)
}),
("Account information", {
"fields": (
"is_removed",
),
}),
("Dates", {
"fields": (
("date_joined", "modified",),
),
})
)
list_filter = ('is_active', 'is_removed',)
The problem is now that when I start up the server, I get the following error:
django.core.management.base.SystemCheckError: SystemCheckError: System check identified some issues:
ERRORS:
<class 'accounts.admin.SoftDeletableNamedUserAdmin'>: (admin.E012) There are duplicate field(s) in 'fieldsets[2][1]'.
<class 'accounts.admin.SoftDeletableNamedUserAdmin'>: (admin.E012) There are duplicate field(s) in 'fieldsets[3][1]'.
<class 'accounts.admin.SoftDeletableNamedUserAdmin'>: (admin.E012) There are duplicate field(s) in 'fieldsets[4][1]'.
I looked at the documentation to see if the way these tuples are defined have changed, but I couldn't spot a difference. What is going wrong here?
Print/log fieldsets and remove any duplicates. For example, it looks as if email may be included explicitly and in BASE_FIELDS.
It looks like the check wasn't as strict as it should be in previous versions of Django. This was fixed by ticket 29322 in Django 2.1.

Database error: no such table: auth_user. Extending AbstractUser and using model to register on admin

I'm trying to use AbstractUser to add a field to Django's standard User model. This is my code:
class GUser(AbstractUser):
uuid = UUIDField(auto=True)
This has been successful because from the shell I can say,
>>> a = GUser.objects.all()
>>> a
[<GUser: User1>]
>>> a[0].uuid
UUID('7d1f0b7b52144a2ea20db81ce74741e3')
The problem I am having is registering a new user from the /admin. When I create a new user I get a Database error:
no such table: auth_user
Before I get more into it, here is my forms.py:
class GUserChangeForm(UserChangeForm):
class Meta:
model = get_user_model()
class GUserCreationForm(UserCreationForm):
class Meta:
model = get_user_model()
def clean_username(self):
username = self.cleaned_data["username"]
try:
get_user_model().objects.get(username=username)
except get_user_model().DoesNotExist:
return username
raise forms.ValidationError(self.error_messages['duplicate'])
And my admin.py:
class GUserAdmin(UserAdmin):
form = GUserChangeForm
add_form = GUserCreationForm
fieldsets = (
(None, {'fields': [('username', 'password')]}),
('Personal info', {'fields': ('is_active','is_staff','is_superuser','groups', 'user_permissions')}),
('Important dates', {'fields': ('last_login', 'date_joined')}),
#('Universal ID', {'fields': ('uuid')})
)
admin.site.register(GUser,GUserAdmin)
I read that when this has happened to other people they implemented their own Forms (as I did) to overwrite clean_username(self):
However I don't think this is getting called when I try to add a user from the admin. The auth.forms.py file is getting called even though I register my GUserAdmin.
Also, when I delete my database (sqlite3) and then call python manage.py syncdb, I see that a auth_user table is actually not getting created.
Yes, I have included AUTH_USER_MODEL in settings.py.
Any help would be greatly appreciated.
I have read:
https://docs.djangoproject.com/en/1.5/topics/auth/customizing/#custom-users-and-the-built-in-auth-forms
Along with tons of SO posts but none of them seem to fix the issue I'm having.
Perhaps the error lies in incorrect zeroing of the database.
'Database error: no such table: str'
To delete the database, delete only database & all migrations in the migration packages(like 0001_initial.py and etc.).
Do not delete all migration packages and file "init.py". If you did this, create them. Django will not create them again.
And after, do not remember run makemigrations & migrate.
So deleted all the work I had done with this and moved on with the standard user so that I could make progress. Then one day I went back to it and managed to get it working in an hour.
I'll post the code for reference but I can't really pin point what made the difference. I do know that the creation forms and stuff were not necessary.
models.py
class PropaUser(AbstractUser):
uuid = UUIDField(auto=True)
admin.py
from django.contrib import admin
from login.models import PropaUser
admin.site.register(PropaUser)
settings.py
AUTH_USER_MODEL = "login.PropaUser"
other models.py
class Word(models.Model):
user = models.ManyToManyField(settings.AUTH_USER_MODEL)
deck = models.ManyToManyField(Deck)
word = models.CharField(max_length=100)
def __unicode__(self): # Python 3: def __str__(self):
return self.word
This is what is working. I do not know what was causing all the issues before because I think I tried this method before posting this question. This may not be a satisfactory answer but this is what is working. Earlier I was also confused about what it takes simply to add a field to the existing User. This is it.

Django: xyz.fieldsets[0][1]['fields'] refers to field '123' that is missing from the form

I have little doubt that this will be a really stupid question. But I really can't figure it out so I'll ask it anyway.
In /svsite/src/svsite/member/models/svuser.py (a little unusual location, see this question Place Django admin forms in different files).
from django.contrib import admin
from django.contrib.auth.models import User
from django.contrib.auth.admin import UserAdmin, UserChangeForm as DjangoUserChangeForm
from svsite.member.models.svuser import svUser
class UserChangeForm(DjangoUserChangeForm):
class Meta:
pass
class svUserAdmin(UserAdmin):
form = UserChangeForm
readonly_fields = ('date_joined', 'last_login', 'last_update', )
fieldsets = \
(
(
'Login',
{
'classes': ('collapse', ),
'fields':
(
'username',
'password',
'is_active',
'email_verified',
'awaiting_user_confirmation',
),
}
),
(
'Personal info',
{
'fields':
(
'first_name',
'middle_name',
'last_name',
),
}
),
)
[...]
In the model I have at /svsite/src/svsite/member/admin/svuser.py:
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.models import User, UserManager
class svUser(User):
email_verified = models.BooleanField(default = False)
awaiting_user_confirmation = models.BooleanField(
_('approved by board'), default = False, help_text=_('This user\'s identity was confirmed by the board or another authority.'))
[...]
The error I get:
'svUserAdmin.fieldsets[0][1]['fields']' refers to field 'password' that is missing from the form.
If I comment password, the error moves to the next field. Independent if it's a default user model field or one I added in the svUser inherited from user. Very surprisingly (to me), username seems to be the only field that works, no problems on that one.
I found this question Django ModelAdmin - fieldsets ... field 'date' missing from the form and even though the fields are not auto_now, I added them to readonly_fields and that made the error go away. Obviously though, making all fields read-only is not an option.
It's probably something stupid not really related to code but I really can't find it, seems to me it really should be working. Any help is greatly appreciated!
The problem appears to be because you're using a ModelForm for a model that you are not editing.
I tried a simliar situation and got a similar error pattern.
class UserChangeForm(DjangoUserChangeForm):
class Meta:
model = svUser # update the model - default form points to User

How to display comments in Django Admin?

I'm using django.contrib.comments for allowing users to comment on a blog.
How is it possible to make the comments display on the Django Admin /admin/comments/comment/ and make them clickable for editing?
[Here should be an image, but since this is my first question and I have no credit, it is not allowed to include images]
The comments can be accessed via /admin/comments/comment/comment_id/ and edited without problems.
Any ideas how to get that solved?
Looking at django.contrib.comments.admin, it should be already visible in your admin panel, provided you added 'django.contrib.comments' to INSTALLED_APPS.
EDIT:
Second look at admin.py from Comments app revelaed that CommentsAdmin.list_display doesn't contain the comment itself. So I would either inherit from that CommentsAdmin, override list_display and then unregister and re-register Comment with MyNewCommentsAdmin - or I would just monkey-patch CommentsAdmin. Whichever works.
Thank you Tomasz,
The problem was 'content_type' in list_display, which resulted in nothing at all displayed. Removing it from MyCommentsAdmin resolved the problem:
app/admin.py:
class MyCommentsAdmin(admin.ModelAdmin):
fieldsets = (
(_('Content'),
{'fields': ('user', 'user_name', 'user_email', 'user_url', 'comment')}
),
(_('Metadata'),
{'fields': ('submit_date', 'ip_address', 'is_public', 'is_removed')}
),
)
list_display = ('name', 'ip_address', 'submit_date', 'is_public', 'is_removed')
list_filter = ('submit_date', 'site', 'is_public', 'is_removed')
date_hierarchy = 'submit_date'
ordering = ('-submit_date',)
raw_id_fields = ('user',)
search_fields = ('comment', 'user__username', 'user_name', 'user_email', 'user_url', 'ip_address')
admin.site.unregister(Comment)
admin.site.register(Comment, MyCommentsAdmin)
urls.py:
from django.contrib import admin
admin.autodiscover()
import app.admin
add to answer Meilo:
if you use standard comment's framework (like: #in url.py
url(r'^comments/', include('django.contrib.comments.urls')),
you wish overwrite behavior comments model, you need import
#apps.admin.py
from django.contrib.comments.models import Comment