how to hide some models in django grappelli admin? - django

How to hide some of the models?
I need them registred to be used by other models, while calling via FK or nested etc.
I found one solution which is rather much about view layer of (MVC)
http://blog.jholster.com/post/1534211028/hide-app-names-in-django-admin
I would like to set it in admin.py, that some of registred models are hidden.

If the models are in your application, just don't register them in the first place. If the model is in a third party app like the django.contrib.auth then use AdminSite unregister method. You can put this in any admin.py or urls.py important is to be discovered by the admin.autodiscover.
# admin.py
from django.contrib.auth.models import User
admin.site.unregister(User)

Related

Django Custom User Model Best Practice: User = get_user_model()?

I'm trying to create a custom user class and I'd like to know the best practice for implementing referencing the new user. After following the Django docs method of implementing the custom user as follows in models.py:
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
pass
And settings.py
AUTH_USER_MODEL = 'myapp.MyUser'
And admin.py
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import User
admin.site.register(User, UserAdmin)
The Django docs say to use settings.AUTH_USER_MODEL in place of user specifically for ForeignKeys and OnetoOneField, but it's not clear about other instances.
My question is specific to how to refer to the custom user class in views.py. Before defining the user class I was using
from django.contrib.auth.models import User
But after defining a custom class this is no longer correct. I've seen boilerplate code use this method in the beginning of views.py:
from django.contrib.auth import get_user_model
User = get_user_model()
Is this the best practice for referencing the custom user? Or should I just be using settings.AUTH_USER_MODEL in place of where I previously had User?
Using settings.AUTH_USER_MODEL will load the user class lazily after all django apps are loaded. Calling get_user_model() on a module level when your app is initially loaded may result in that the user model app is not loaded and also circular imports.
Update: I read two specific questions:
How to correctly access the user model, contrib or custom.
Djangos get_user_model() is quite simply a call to django.apps get_model() using the settings.AUTH_USER_MODEL. If you are writing apps that might be reused in other projects with other user models, use the get_user_model call. Always. Then it doesn't matter what the user model is.
If you have created your own core.User model and is very confident that your code will only be used in this project, from core.models import User works as well.
When to use the string representation from settings instead of fetching the model.
The string representation will in the end usually call the same django.apps get_model() anyway. By giving a string instead of the class itself in Foreignkeys, OneToOneFields etc you simply don't require the model to be looked up during django app imports, where the user model may not yet be available. So using string representation is simply deferred loading of a model. The same goes for all models.
An also during djangos different major versions this behavior have changed, which is another topic. Notice that get_user_model() have been updated in Django 1.11 for import usage.
https://docs.djangoproject.com/en/1.11/topics/auth/customizing/#referencing-the-user-model
you can go with get_user_model instead User
from django.contrib.auth import get_user_model
User = get_user_model()
get_user_model will Returns the User model that is active in this project.
if you modify(adding new field into it) default User table you need to use get_user_model it will return active User table.
BTW User will return native from django.contrib.auth.models

Django-Oscar un-registering a class from admin panel

I would like to un-register a ModelAdmin class from the default oscar app.
I created an admin.py file and did the following but was unable to obtain the desired result.
from django.contrib import admin
from oscar.apps.address.admin import *
admin.site.unregister(UserAddressAdmin)
admin.site.unregister(CountryAdmin)
The model is still displayed in the admin panel.
I want the model to be created but I do not want to display the same in the admin panel.
Any help would be greatly appreciated. Thanks.
admin.site.unregister takes the Model class that you want to unregister - you are passing it a ModelAdmin class, which it will just ignore. This should work:
from oscar.core.loading import get_model
admin.site.unregister(get_model('address', 'useraddress'))
admin.site.unregister(get_model('address', 'country'))
However this is all unnecessary! Why don't you just put an empty admin.py file in your fork of the app? Currently you are importing Oscar's admin registrations only to manually unregister all of them again. Just don't import them.

Django Admin tables not displaying correctly

Has anyone seen this before? I've tried making new apps, projects, etc.
All thats in my admin.py file is:
from django.contrib import admin
from . models import UserProfile, Tribe, Membership
# Register your models here.
admin.site.register(Tribe)
admin.site.register(Membership)
admin.site.register(UserProfile)
I've not got any static files or css in the app..?
Create a class that inherit admin.ModelAdmin, update the fields to be shown in the list_display tuple, and register TribeAdmin instead of Tribe. Do the same for the rest.
from django.contrib import admin
from . models import UserProfile, Tribe, Membership
# Register your models here.
class TribeAdmin(admin.ModelAdmin):
list_display = ('field_1', 'field_2',)
admin.site.register(Tribe, TribeAdmin)
# admin.site.register(Membership)
# admin.site.register(UserProfile)
For all the available options, have a look at the documentation or an easy to understand beginner tutorial from the DjangoBook (please note its for an outdated Django Version, but fields works with Django 1.8)
With Django 1.8 you can use.
#admin.register(Tribe)
class TribeAdmin(admin.ModelAdmin):
list_display = ('field',)

How to properly extend django User model

I'm trying to extend the default Django's authentication model with additional fields and functionaliy, so I've decided to just go with extending User model and writing my own authentication backend.
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.models import User
class MyUser(User):
access_key = models.CharField(_('Acces Key'), max_length=64)
This is really a basic code yet when trying to syncdb I'm cetting a strange error that Google doesn't know about :
CommandError: One or more models did not validate:
core.sldcuser: 'user_ptr' defines a relation with the model 'auth.User', which has been swapped out. Update the relation to point at settings.AUTH_USER_MODEL.
In my settings.py I've added what I guess is required :
AUTH_USER_MODEL = 'core.MyUser'
Had anyone stumbled upon this error ?
Or maybe I should use a one-to-one way, or a hybrid of 1t1 with proxy ?
What you're doing right now, is creating a subclass of User, which is non-abstract. This means creating a table that has a ForeignKey called user_ptr pointing at the primary key on the auth.User table. However, what you're also doing by setting AUTH_USER_MODEL is telling django.contrib.auth not to create that table, because you'll be using MyUser instead. Django is understandably a little confused :P
What you need to do instead is inherit either from AbstractUser or AbstractBaseUser.
Use AbstractUser if you want everything that User has already, and just want to add more fields
Use AbstractBaseUser if you want to start from a clean state, and only inherit generic functions on the User, but implement your own fields.
REF:
https://docs.djangoproject.com/en/dev/topics/auth/customizing/#extending-the-existing-user-model
https://docs.djangoproject.com/en/dev/topics/auth/customizing/#substituting-a-custom-user-model

Override the Admin.py file of reusable app in Django

I basically have 2 external Django app that are overriding the UserAdmin model.
Each one of these will first unregister the UserAdmin model and then register their own, something like this:
admin.site.unregister(get_user_model())
admin.site.register(get_user_model(), ExternalAppUserAdmin)
I also, in turn, override the UserAdmin:
admin.site.unregister(get_user_model())
admin.site.register(get_user_model(), MyAppUserAdmin)
The problem is that depending on the order of the INSTALLED_APPS in the settings file only the last app will actually override the UserAdmin.
Most of the times these overriding are just InlineModelAdmin inside the AdminUser, so what I've done so far is to import the external app's InlineModelAdmin models and insert them in my own admin.py. For example:
from relationships.admin import RelationshipInline
....
class BaseProfileAdminStacked( NestedModelAdmin, GuardedModelAdmin):
inlines = [BaseProfileInline, RelationshipInline,]
....
admin.site.unregister(get_user_model())
admin.site.register(get_user_model(), BaseProfileAdminStacked)
But this seems a little hacky to me, because for example:
The first external app will unregister the UserAdmin, then register it again with its own customization
The second external app will do the same, actually overriding the first one
My own app should then import all the AdminInline from the external apps and include them in my own registration of the UserAdmin
Isn't this a waste of effort? Do you have a better idea to do so?