I have the following model and TabularInline subclasses:
class SomeModel(models.Model):
name = models.CharField(max_length=50)
class SomeModelInline(admin.TabularInline):
model = SomeModel
class SomeOtherModelAdmin(admin.ModelAdmin):
inlines = [SomeModelInline]
Without explicitly specifying the TabularInline's fields, Django's admin shows the fields "id" and "name". However, when I try and do:
class SomeModelInline(admin.TabularInline):
model = SomeModel
fields ['id','name']
Django throws the ImproperlyConfigured exception:
'SomeModelInline.fields' refers to field 'id' that is missing from the form.
What's going on here? Why can't I explicitly specify the id, even though Django's clearly capable of accessing it?
Ids are non-editable, by default inline shows the editable fields, but you can show the non-editable fields as well
From django docs
fields can contain values defined in ModelAdmin.readonly_fields to be
displayed as read-only.
So first add 'id' to readonly_fields, then add it to fields
Related
I have two models:
class ModelA(models.Model):
id = models.AutoField()
name = models.ManyToManyField(ModelB)
class ModelB(models.Model):
id = models.AutoField()
In the Django Admin page, I noticed that I now see a table called "modelA-modelB relationships". Is this the expected outcome?
If so, how can I rename this to be something more user-friendly? I've tried several parameters verbose_name, related_name, and db_table for the ManytoManyField and none seem to overwrite the default name.
I'm trying to add a readonly field in a form.
The model Folder is registered in admin site. The FolderAdminForm defines the custom field statistics. There isn't statistcs field in the Folder model, I just want to put some readonly data on the form. This data is defined in the template.
But I get a error whenever the user doesn't have edit permission. If the user only have the view permission,this error is raised:
AttributeError: Unable to lookup 'statistics' on Folder or FolderAdmin
Here is my code:
class CustomWidget(forms.Textarea):
template_name = 'widget.html'
class FolderAdminForm(forms.ModelForm):
class Meta:
model = Folder
fields = ('field1', 'field2', 'field3',)
statistics = forms.Field(
widget=CustomWidget,
label='Estatísticas',
help_text='Estatísticas da pasta',
)
According to the last part of this answer, you could try to override the forms __init__() method and assign the fields initial attribute.
This could look like:
def __init__(self, *args, **kwargs):
# only change attributes if an instance is passed
instance = kwargs.get('instance')
if instance:
self.base_fields['statistics'].initial = 'something'
super().__init__(*args, **kwargs)
Does this work for you?
The error only occurred whenever I tried to open a folder instance without edit permission (i.e. with read only permission). Therefore, django consider the statistics field as a read only field and then search for a label for this field. Django look for this label in Model, ModelAdmin. Since none of them has the 'statistics' attribute, the error is raised.
So, this worked for me:
class FolderAdminForm(forms.ModelForm):
class Meta:
model = Folder
fields = ('field1', 'field2', 'field3',)
labels = {'statistics': 'Estatísticas'}
statistics = forms.Field(
widget=CustomWidget,
label='Estatísticas',
help_text='Estatísticas da pasta',
)
Therefore, whenever django looks for a label for statistics, it finds this label and the error is not raised. I don't know why it doesn't recognize the label passed as a Field parameter.
In one of my django models, I have a field like this:
modified = models.DateTimeField(auto_now=True)
I thought, when creating a ModelForm for this model, I could just skip this field, and Django would populate it automatically.
My ModelForm:
class FooForm(forms.ModelForm):
class Meta:
model = Foo
fields = ['text', 'name', 'description'] # notice - modified field not included -
# should not be shown to the user
But, even though it didn't show up in the form, when submitting, when creating a new object, I got an exception:
IntegrityError at /url/ - null value in column "modified" violates not-null constraint
How can I make this work?
The auto_now field is not populated automatically in such a case.
You need to use auto_add_now, so the field definition looks like this:
modified = models.DateTimeField(auto_now_add=True)
Then, django will add the date automatically if the field is not shown.
You just need to provide a default value to the field.
This can be done as follows:
from datetime import datetime
modified = models.DateTimeField(default=datetime.now)
Implementing custom user for my project,
here is my account/models.py
class myUser(AbstractBaseUser, PermissionsMixin):
#blah
date_joined = models.DateTimeField(auto_now_add=True)
#blah
and my account/admin.py
class myUserDetail(admin.ModelAdmin):
list_display = ('email','password','is_active','is_staff','date_joined',)
fields = list_display
admin.site.register(myUser, myUserDetail)
The list_display works fine, but when I click into a user,
error is raised :
Unknown field(s) (date_joined) specified for myUser. Check fields/fieldsets/exclude attributes of class myUserDetail.
In fact it exists in postgres...
Please help!
The error is being triggered when the ModelForm is created automatically for the admin, specifically if there are missing fields. Because you are using auto_now_add=True, which implicitly sets editable=False, the field cannot be included in the automatically generated form. Because of this, an error is triggered.
I would recommend specifying fields and list_display independently, as they aren't actually the same.
When you use a custom User model in Django you should add the following line to your settings:
AUTH_USER_MODEL = 'accounts.MyUser'
I also think you should subclass from AbstractUser which is an abstract base class implementing a fully featured User model with admin-compliant permissions, and includes email, date_joined, etc. fields.
You can read more about customizing the user model in the Django documentation.
I have simply model class:
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
I want to set attribute title unmodifiable in django admin. What should I do to set this?
Add the field name to readonly_fields of that model's ModelAdmin class. According to the documentation:
By default the admin shows all fields as editable. Any fields in this option (which should be a list or tuple) will display its data as-is and non-editable.
In your situation this looks like:
readonly_fields = ("title",)