How to add multiple models from a Django app to adminpanel? - python

To add a single model from an app in to the /admin area I have done like so:
from django.contrib import admin
from wiki.models import Page, Category, CategoryItem
# register Pages for use in Django admin
class PageAdmin(admin.ModelAdmin):
pass
admin.site.register(Page, PageAdmin)
which works fine for a single model, but when I try to register the other two (Category and CategoryItem), it breaks down. What is the correct way of adding multiple models for a single Django app in the admin interface?

in django 1.5 we do following:
from django.contrib import admin
from wiki.models import Page, Category, CategoryItem
for cls in (Page, Category, CategoryItem):
admin.site.register(cls)

This is default way:
class PageAdmin(admin.ModelAdmin):
pass
class CategoryAdmin(admin.ModelAdmin):
pass
class CategoryItemAdmin(admin.ModelAdmin):
pass
admin.site.register(Page, PageAdmin)
admin.site.register(Category, CategoryAdmin)
admin.site.register(CategoryItem, CategoryItemAdmin)
If you've got some unhandled exception, add it to the question, so we can find out what's broken.

If you are not making changes in the models display in admin portal no need to create Admin Items, you can pretty much register it like :
from django.contrib import admin
from wiki.models import Page, Category, CategoryItem
admin.site.register(Page)
admin.site.register(Category)
admin.site.register(CategoryItem)

Related

Where to best execute database operations using Django framework?

Thanks in advance for any help. I am new to django specifically as well as web development in general. I have been trying to teach myself and develop a website using the Django framework and while everything is working so far, I am not sure if I am really doing things in the best possible way.
Typically, within my django app, I will have certain points where I want to modify the contents of my database model in some way. A typical use case is where I have button on my site that says "Add a post":
models.py:
from django.db import models
# data model import
from django.contrib.auth.models import User
# Create your models here.
class Post(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
post = models.CharField(max_length=1024)
urls.py:
from django.urls import include, path
from . import views
urlpatterns = [
path('', views.post, name='new_post'),
path('post_exec', views.post_exec, name='post_exec'),
]
views.py:
from django.contrib import messages
from django.shortcuts import render, redirect
# import data models
from django.contrib.auth.models import User
from .models import Post
def post(request):
# make sure the user has privileges
user = User.objects.get(id = request.user.id)
if not user.is_superuser:
return redirect('home')
return render(request, 'post.html')
def post_exec(request):
# make sure the user has priveledges
user = User.objects.get(id = request.user.id)
if not user.is_superuser:
return redirect('home')
# create the post
new_post = Post.objects.create()
new_post.user = user
new_post.post = request.POST['post']
new_post.save()
# this could redirect to a confirmation page or something too
return redirect('home')
You can see what I am doing here is that everytime I need a change to the database due to user input, I am executing the code to do the requested database change in a django view and then redirecting to another page following completion of the database change. While this works, it feels kind of clunky (you end up needing pages that you never actually use), it seems pretty sketchy in terms of security (although I am checking for credentials on each page), and I imagine there is a better way to do this.
Can any experience Django developers offer some advice for how I should be best structuring my project for these specific types of common database operations?
The Django's views is a good place to organize the project's CRUD system so users can manage their data. You can use the class-based views to group the GET, POST etc requests. Also there are better ways of using the authorization system with the login_required() decorator, the LoginRequiredMixin class and other solutions that you can rich here

Django Admin template override

I am following the tutorial on django website to create my first django app.
Now I am stuck trying to override Django Admin template.
My project directory is this:
First I tried creating a new admin template in the surveys app. It works.
Then, I tried with the override function. For this I created at surveys/admin.py the following code:
from django.contrib.admin import AdminSite
from django.utils.translation import ugettext_lazy
class SurveysAdminSite(AdminSite):
site_header = ugettext_lazy('Test administration')
surveys_admin_site = SurveysAdminSite()
And add to computationalMarketing/urls.py the following:
from .admin import surveys_admin_site
urlpatterns = [
path('admin/', surveys_admin_site.urls, name='admin'),
]
It doesn't work, so I search, and tried something different. Add this same previous code to surveys/urls.py. Neither works. Then I rollback the changes to save the code to computationalMarketing/urls.py, but this time I changed the code from surveys/admin.py to computationalMarketing/admin.py (in fact I created the file because it doesn't exists.
It works and now I see the site header that I want, but I get You don't have permission to edit anything. I have seen that is something related with superuser creation, but until now I was able to admin my surveys app without problem, so I believe in some solution related with override properly the admin.py at surveys app
Does anybody knows why this does not works as expected?
You are overriding the complete admin site. You may want to override only specific templates and keep using the default admin site.
A first approach to solve your problem is to add models to your admin site:
surveys/admin.py:
from django.contrib.admin import AdminSite
from django.utils.translation import ugettext_lazy
from surveys.models import OneModel, OtherModel
class SurveysAdminSite(AdminSite):
site_header = ugettext_lazy('Test administration')
surveys_admin_site = SurveysAdminSite()
surveys_admin_site.register(OneModel)
surveys_admin_site.register(OtherModel)
And maybe use ModelAdmin objects to add advanced behavior.
Hope this helps.

Export button is not visible with django-import-export package

I am trying to use django-import-export module in my admin and here are my settings
admin.py
from import_export.admin import ImportExportMixin, ImportMixin, ExportActionModelAdmin, ImportExportActionModelAdmin
class RegistrationAdmin(ImportExportActionModelAdmin):
list_display = ('user', 'activation_key_expired')
raw_id_fields = ['user']
search_fields = ('user__username', 'user__first_name', 'user__last_name')
admin.site.register(RegistrationProfile, RegistrationAdmin)
With the above code, i can able to see an Import button in admin as below
But i can't able to see Export option, so what's the problem what am i missing here ?
I have seen some ticket about export button permission here
https://github.com/django-import-export/django-import-export/issues/38 ? can anyone please let me know what need to be done in order for Export to appear ?
By the way i am using django suit as my admin theme
You need to use ImportExportModelAdmin
ImportExportActionModelAdmin only adds the export to the list of things you can do to selected items (see the dropdown in your screenshot)
Docs for ImportExportActionModelAdmin state
Export functionality is implemented as an admin action.
You need to use ImportExportModelAdmin
Eg:
from django.contrib import admin
from .models import Question, Choice
from import_export.admin import ImportExportModelAdmin
# Register your models here.
#admin.register(Question)
class ViewAdmin(ImportExportModelAdmin):
pass
#admin.register(Choice)
class ViewAdmin(ImportExportModelAdmin):
pass

Django custom user admin change_password

I'm successfully using a custom user model with django.
The last thing to get working is the "AdminChangePasswordForm" for superusers to change any users password.
currently the change password link from admin:myapp:user gives a 404
The answer.
Override get_urls
and override UserChangeForm to have the correct url.
So I had similar problem. When I tried to change user password from admin I got url to "/admin/accounts/siteuser/password/" (siteuser is the name of my custom user model) and 404 error with this message: "user object with primary key u'password' does not exist."
The investigation showed that the problem was due to bug in django-authtools (1.4.0) as I used NamedUserAdmin class to inherit from.
So the solution is either (if you need to inherit from any custom UserAdmin like NamedUserAdmin from django-authtools):
from django.contrib.auth.forms import UserChangeForm
from authtools.admin import NamedUserAdmin
class SiteUserAdmin(NamedUserAdmin):
...
form = UserChangeForm
...
or just inherit from default django UserAdmin:
from django.contrib.auth.admin import UserAdmin
class SiteUserAdmin(UserAdmin):
pass
It seems it's a "bug" in 1.7.x, and fixed in 1.8.x, which set the url name, so you do have to override get_urls():
from django.contrib.auth.admin import UserAdmin as AuthUserAdmin
from django.conf.urls import url
class UserAdmin(AuthUserAdmin):
def get_urls(self):
return [
url(r'^(.+)/password/$', self.admin_site.admin_view(self.user_change_password), name='auth_user_password_change'),
] + super(UserAdmin, self).get_urls()
URL:
password_change_url = urlresolvers.reverse('admin:auth_user_password_change', args=(1,))

django admin registering dynamic model from action

I have strange problem. In admin.py I can say:
admin.site.register(MyModel)
and this is obviously fine. Now I want this model to be loaded automatically as an result of user action:
def user_action_from_admin_panel(......):
.....
admin.site.register(MyModel)
MyModel class gets shows up in the admin as plain text without links.
Any ideas to solve this?
May be you need this
from django.core.urlresolvers import clear_url_caches
from django.utils.importlib import import_module
def user_action_from_admin_panel(......):
.....
admin.site.register(MyModel)
reload(import_module(settings.ROOT_URLCONF))
clear_url_caches()
models created dynamically will not show up in the admin unless their app_labels match up with packages listed in INSTALLED_APPS
This is again by design, and should not be considered a bug.
Make sure you are adding app_label while creating a model
model = create_model('DynamicModel', app_label='existing_app')
Also reload your url conf so that new model gets links
# after creating model
from django.utils.importlib import import_module
reload(import_module(settings.ROOT_URLCONF))
Source: https://code.djangoproject.com/wiki/DynamicModels#Admininterface
I have black links if I don't permissions to add/change.
Try re-define your admin class:
class MyModelAdmin(admin.ModelAdmin):
def has_add_permission(self, request):
return True
def has_change_permission(self, request):
return True
...
admin.site.register(MyModel, MyModelAdmin)
The reason possibly is because Django couldn't find any URL match with that model for admin section. Hence, that model line in admin area will be set at disabled and no additional add or edit links.
For some cases, your code for registering models are triggered after the building of admin URLs (django.contrib.admin.site.AdminSite.get_urls()).A workaround solution is to update the whole admin urlpatterns of the global URLs, or using a Django apps named django-quickadmin, it will automatically load all custom models into admin without making any additional code.

Categories