if there is relation like:
B.ForeignKey(A)
django can show it in one admin page by TabularInline:
admin.py
from django.contrib import admin
from myapp2 import models
# Register your models here.
class TabularInlineB(admin.TabularInline):
model=models.B
class AdminA(admin.ModelAdmin):
inlines=[TabularInlineB, ]
admin.site.register(models.A, AdminA)
models.py
from django.db import models
# Create your models here.
class A(models.Model):
name=models.CharField(max_length=10)
class B(models.Model):
name=models.CharField(max_length=10)
a=models.ForeignKey(A)
.the output is like:
but if we add another ForeignKey relation to B like below,
B.ForeignKey(A)
C.ForeignKey(B)
then How I can show all models in one admin page?
admin.py
from django.contrib import admin
from myapp2 import models
class TabularInlineC(admin.TabularInline):
model=models.C
class TabularInlineB(admin.TabularInline):
model=models.B
inlines=[TabularInlineC, ]
class AdminA(admin.ModelAdmin):
inlines=[TabularInlineB, ]
admin.site.register(models.A, AdminA)
.models.py
from django.db import models
# Create your models here.
class A(models.Model):
name=models.CharField(max_length=10)
class B(models.Model):
name=models.CharField(max_length=10)
a=models.ForeignKey(A)
class C(models.Model):
b=models.ForeignKey(B)
name=models.CharField(max_length=10)
the output dose not show C:
I had the same issue and I managed to do it. I don't know if it's exactly what you need but let me know if it's not I'll remove my answer.
You can do it like that:
Admin.py
from django.contrib import admin
from myapp2 import models
class TabularInlineC(admin.TabularInline):
model=models.C
class TabularInlineB(admin.TabularInline):
model=models.B
class AdminA(admin.ModelAdmin):
inlines=[TabularInlineB, TabularInlineC ]
admin.site.register(models.A, AdminA)
That will render two inlines having each a section in the admin page of model A. Note that in this code, both model B and Model C have foreign key to model A. Indeed, this is not exactly the same pattern you are using in your question but it is, in my opinion, the simplest way of achieving what you want. The fact that you point two models to the same, allow you to consider this Model has the parent model. So, if you can find a common field to point to, you will be able to add two inlines in the same form since both models will have a link to Model A.
Also, another interesting thing you can do is add classes = ['collapse'] to both class TabularInlineB and class TabularInlineC this will allow collapsable on those two sections of your admin page.
Hope it helps !
EDIT
If you absolutely need to render only one inline that include both models, I'm also not sure if it is possible out of the box with Django.
Related
I want to customize Django Admin to have specific section for objects of my models (Such as Post or Product models) that use as an archive section.
I now that, I need one field in my models that shown status of objects (Such as is_archive field), but I don't have any idea about how to display them in Django Admin.
Does anyone have an opinion on this?
Create Proxy model for model you need
Create separate section in your admin panel for this proxy model
Override get_queryset() for it.
models.py
from django.db import models
class Post(models.Model):
...
is_archive = models.BooleanField(default = False)
...
class PostProxy(Post):
class Meta:
proxy = True
admin.py
from django.contrib import admin
from .models import *
#admin.register(Post)
class PostAdmin(admin.ModelAdmin):
...
#admin.register(PostProxy)
class PostProxyAdmin(admin.ModelAdmin):
...
def get_queryset(self, request):
return super().get_queryset(request).filter(is_archive=True)
I'm working on a simple DRF API and I can't seem to access one of my many models from the admin site, although I can access some models from the same Application, please help!
project/app/models.py looks something like this:
class ImportantModel(models.Model):
name = # character field
relation1 = # foreign key
relation2 = # foreign key
...
class Contact(models.Model):
information = # character field
...
The problem is I can see the Contact model(and multiple other models) from the admin site(http://localhost:8000/admin/) but ImportantModel is not showing. Thank you in advance.
You need to register your model in admin.py file.
Well I was in same problem because the problem is I registered my models in admin.py file but in a wrong way
wrong way:
from django.contrib import admin
from .models import Article
from .models import User
# Register your models here.
admin.register(Article)
admin.register(User)
And the right way is
right way:
from django.contrib import admin
from .models import Article
from .models import User
# Register your models here.
admin.site.register(Article)
admin.site.register(User)
The built-in django group model on the admin site only shows name:
but I want to include additional fields that are already part of the group model, such as id.
I have tried adding these fields using the following admin.py setup:
from django.contrib import admin
from django.contrib.auth.models import Group
class GroupsAdmin(admin.ModelAdmin):
list_display = ["name", "pk"]
class Meta:
model = Group
admin.site.register(Group, GroupsAdmin)
But this returns the error:
django.contrib.admin.sites.AlreadyRegistered: The model Group is already registered.
I have successfully registered other models (I've created) on admin but the above doesn't work for those models that are already a part of django.
How can I add fields in the admin model for Group?
The accepted answer is correct, however, I would like to point out that you could inherit from the GroupAdmin if your goal is only extending that is, and not modifying:
from django.contrib.auth.admin import GroupAdmin
class GroupsAdmin(GroupAdmin):
list_display = ["name", "pk"]
admin.site.unregister(Group)
admin.site.register(Group, GroupsAdmin)
You need to unregister it first from the built-in Group model and then register it again with your custom GroupAdmin model.
So:
class GroupsAdmin(admin.ModelAdmin):
list_display = ["name", "pk"]
class Meta:
model = Group
admin.site.unregister(Group)
admin.site.register(Group, GroupsAdmin)
Also, the Meta class is not required. You can remove it.
Any suggestion on this please?
Initially I had class Customer(): in models.py
This is how the code in admin.py looked
from django.contrib import admin
from booknowapp.models import Customer
# Register your models here.
admin.site.register(Customer)
Now that I have added two new classes to models how do I register in admin for other new two classes to appear in the app? I am not sure of the syntax to be used.
If your added two new classes of models are ModelClass1 and ModelClass2 then you can register multiple models in admin.py like :
from django.contrib import admin
from booknowapp.models import Customer, ModelClass1, ModelClass2
myModels = [Customer, ModelClass1, ModelClass2] # iterable list
admin.site.register(myModels)
OR
You can repeat admin.site.register for other two new classes just like your Customer .
If you extend the syntax that you have already used, it would simply be:
from django.contrib import admin
# wrap the line if it's too long
from booknowapp.models import (
Customer,
SecondModel,
ThirdModel
)
# Register your models here.
admin.site.register(Customer)
admin.site.register(SecondModel)
admin.site.register(ThirdModel)
However, this will only give you the default admin model list views - which you will probably want to extend.
class CustomerAdmin(admin.ModelAdmin):
"""Specialised admin view for the Customer model."""
# set the fields to display
list_display = ('name', 'address', 'registered')
# register your Customer model, using the CustomerAdmin view
admin.site.register(Customer, CustomerAdmin)
The ModelAdmin has lots more functionality that you can leverage - search fields, filtering, custom fields, custom actions ('Activate customer'), which you can read about here - http://www.djangobook.com/en/2.0/chapter06.html#custom-modeladmin-classes
I'm trying to extend default Django's model with a new field.
In localsite/models.py I have the following code:
from django.db import models
from django.utils.translation import ugettext_lazy as _
from satchmo_store.contact.models import Organization
class OrganizationExtra(models.Model):
organization = models.OneToOneField(Organization,
verbose_name=_('Organization'), primary_key=True )
vat_number = models.CharField(_('VAT'), max_length=12)
Followed with run of ./manage.py syncdb which did created a new table for above model. So far so good.
Now I'm trying to add this new field in related Organization view in the admin interface.
The following code registers the new menu, however the new vat_number field is not displayed in view of the related Organization model.
from django.contrib import admin
from localsite.models import ProductResource, OrganizationExtra
admin.site.register(OrganizationExtra)
The original Organization model is registered with
from satchmo_store.contact.models import Organization
from django.contrib import admin
class OrganizationOptions(admin.ModelAdmin):
list_filter = ['type', 'role']
list_display = ['name', 'type', 'role']
admin.site.register(Organization, OrganizationOptions)
Any idea how to insert my new field without touching original Satchmo sources ?
See the docs as usual.
One possible way is to create new MyOrganization derived from Organization and register it in place of satchmo one
Your models.py
from django.db import models
from django.utils.translation import ugettext_lazy as _
from satchmo_store.contact.models import Organization
class MyOrganization(Organization):
vat_number = models.CharField(_('VAT'), max_length=12)
Your admin.py
from django.contrib import admin
from localsite.models import MyOrganization
from satchmo_store.contact.models import Organization
from satchmo_store.contact.admin import OrganizationOptions
admin.site.unregister(Organization)
admin.site.register(MyOrganization, OrganizationOptions)
Another possible solution (if you wish to stick with OrganizationExtra) is to create custom form for Organization for admin interface and again reregister model. By it seems to me as more boilerplate and result will be the same.
NB: in both cases DB structure would be the same, i.e. extra table would be created.