Remove the "Add" functionality in Django admin [duplicate] - python

This question already has answers here:
Django Admin - Disable the 'Add' action for a specific model
(5 answers)
Closed 10 years ago.
Is there a way to remove the "Add" functionality on the Django admin site? For certain entities, I only want the Django admin to be able to view them or change existing ones, but not add new ones.

See: Django Admin - Disable the 'Add' action for a specific model for true solution.

Sure, you can customize admin VERY granularly by following the instructions here -- I believe that what you want can be obtained in part by overriding ModelAdmin.save_model(self, request, obj, form, change) in your own ModelAdmin subclass, to ensure nothing happens on the store when change is false (i.e. an attempt to add rather than change), and in part by overriding ModelAdmin.add_view(self, request, form_url='', extra_context=None) to display an "add view" that makes it very clear to the admin that they're NOT going to be allowed to add object through this route. I haven't actually done the specific admin customization you require, but I've done others and they do seem to work pretty smoothly!

You can customize the permission for each user group from within the admin interface: try going to /admin/auth/group and it should be straightforward from there.
This won't be as granular as the solution offered by the earlier answer, but it will take care of most of your needs without needing to customize the admin.

If you change the permissions to restrict access then you'll still get the plus sign by a FK/MtM field. Clicking that will open a popup window with 'Permission Denied' in it.
You can actually completely remove the plus sign by not simply not registering the model with the admin.
I have a situation where I have predefined categories that I want users to be able to select more than one of. The best way to do this is with a models.ManyToMany field. You can register the model with the admin, enter the data as required and then remove the registration.

An easy effective way is to set max_num=0 for that particular inline.

Satya's suggestion of setting max_num=0 works perfectly.
Per the Django docs on the ModelForm class:
For users with JavaScript-enabled browsers, an "Add another" link is provided to enable any number of additional inlines to be added in addition to those provided as a result of the extra argument.
The dynamic link will not appear if the number of currently displayed forms exceeds max_num, or if the user does not have JavaScript enabled.
and
As with regular formsets, you can use the max_num and extra parameters to modelformset_factory to limit the number of extra forms displayed.
max_num does not prevent existing objects from being displayed

Related

Last seen a user in django

How can i show the time of last seen(be online)of user in django?
Is there any default function or library to import it to do that?
Or if there any code inn github tell me please
**Note : ** when a user close page or disconnect the time update
You should inherit django's AbstractBaseUser in your user model, it already has an inbuilt last_login attribute. In fact it is considered a good practice to inherit AbstractBaseUser for creating your user which is provided in django default auth modules.
There is few options.
you can add a code to your views to check for user or session id (depends on how do you want it to work. for registered users or every users or ... ) and every time a user request for a page, you can update that this user has been active on the site on this time.
but this option seem to be usable when you need to track a user in a small project with few pages.
another option which seem more right to do is to use middleware. by using middleware you don't need to change your code in all of your views. simply make a custom middleware and everything will be done with few lines of code
you can check an example of this middleware here:
Django: How can I check the last activity time of user if user didn't log out?
or
Django get last user visit date
and for disconnected part i think you can't do much with django. and also you can't be sure when user closed the page.
the best option here is to use a javascript code to run like every 10 sec and tell django that the user is still on the page.

Django: make field editable depending on the value of other field

I'm new to Django, and I haven't found the answer yet in the extensive documentation. I'm asking for pointers to research, not for working code. That being said, here's my problem:
In one of my models theres a BooleanField (it gets rendered in the admin form as a checkBox). Let's call it 'A'. It only makes sense to edit other field (say, CharField 'B') if A is checked.
So, is there a way to make B read only, or even changing its content to an empty string, dinamically, if A is checked? Thank you.
(Django 1.5.2, Python 2.7.5)
You're going to need several things to make this work. You may be able to skip some of them depending if you mainly care abut the UI, or the data integrity in the db.
Since the user can (presumably) check/uncheck Field A on the client-side you need some Javascript to enable/disable the appearance of Field B. These docs show how to load custom JS in your ModelAdmin class:
https://docs.djangoproject.com/en/dev/ref/contrib/admin/#modeladmin-asset-definitions
In your ModelForm you may want to do some check in the __init__ method against the value of self.instance.field_a and substitute some kind of ReadOnlyWidget for Field B for the initial display of the form. These docs show how to give your ModelAdmin a custom form class:
https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.form
If you are writing some Javascript to do that dynamically it make be easier to skip this step and just do it client-side.
Finally you can use Django model validation to ensure that Field B is saved with a null value if Field A is checked:
https://docs.djangoproject.com/en/dev/ref/models/instances/#validating-objects

How do I display a confirmation message after a custom admin action with an intermediate page (in Django)?

The built-in actions that come with the Django admin generally display a helpful message after they execute at the top, e.g. saying that a new object was added or what have you.
The docs show how to do it with simple actions that can be represented as methods of the custom ModelAdmin. However, with custom actions that need intermediate pages (covered further down on that same page), I am encouraged to pass the user onto another view. That's great, but it means that I no longer have access to the custom ModelAdmin instance in order to call its message_user() method... Or at least I'm not sure how to get it.
Can you tell me how to get a hold of the current ModelAdmin instance or, if there's a better way, how else to display one of those helpful little messages when I'm done in the other view?
To mimic the ModelAdmin.message_user method you only need to do the following:
from django.contrib import messages
messages.info(request, message)
Adding a message is documented here https://docs.djangoproject.com/en/dev/ref/contrib/messages/#adding-a-message and the way ModelAdmin uses it can be seen here: https://code.djangoproject.com/browser/django/trunk/django/contrib/admin/options.py#L691
Construct a LogEntry and write a custom templatetag to render messages on your intermediat page, for instance:
LogEntry.objects.log_action(
user_id=request.user.id,
content_type_id=ContentType.objects.get_for_model(yourmodel).pk,
object_id=case.id,
object_repr=force_unicode(yourmodel),
action_flag=ADDITION if created else CHANGE)
read more: Django docs (Message Framework)

Multiple versions of django admin page for the same model

In my django admin section, I'd like to show different versions of the admin page depending on what kind of user is currently logged in. I can think of a couple ways this might work, but haven't figured out how to do any of them.
Perhaps I could put logic into the admin.ModelAdmin to look at the current user and change the 'exclude' field dynamically. Does that work? Or maybe run different custom templates based on who's logged in, and have the templates include / exclude the fields as appropriate.
I could register two versions of the admin.ModelAdmin class, one for each type of user, and maybe restrict access through permissions? But the permissions system seems to believe fairly deeply in one set of permissions per model class so I'm not sure how to change that.
I could grab a couple of the widgets that are used in rendering the admin page templates, and include them in my own page that does the one specific job I need powerful users to be able to do.
I could set up multiple AdminSites and restrict access to them through the url / view system. But then I'm not sure how to register different admin.ModelAdmin classes with the different AdminSites.
Any advice on this would be appreciated.
Answer
Thanks for the hint. Here's how I did it...
def get_form(self, request, obj=None, **kwargs):
"""This dynamically inserts the "owners" field into the exclude list
if the current user is not superuser.
"""
if not request.user.is_superuser:
if self.exclude:
self.exclude.append('owners')
else:
self.exclude = ['owners']
else:
# Necessary since Admin objects outlive requests
try:
self.exclude.remove('owners')
except:
pass
return super(OwnersModelAdmin,self).get_form(request, obj=None, **kwargs)
There are quite a few hooks provided in the ModelAdmin class for this sort of thing.
One possibility would be to override the get_form method. This takes the request, as well as the object being edited, so you could get the current user from there, and return different ModelForms dependent on the user.
It's worth looking at the source for ModelAdmin - it's in django.contrib.admin.options - to see if overriding this or any other other methods might meet your needs.

Forms generated through admin in Django

I need to be able to create forms from admin panel. Process would look like this:
I click on "Add form" then I enter email to which the form should be sent and of course several fields (probably thanks to inlines) consisting of field name, type and if it is required. User should be able to view and fill the form and submit it and the data should be sent to the email given in admin.
Everything looks pretty straightforward but from my point of view it need some metaclass programming skills.
Could anyone point me to a goot form builder for Django or at least hand some tips about creating such thing? I found django-forms-builder but it is a bit too restricted imho.
I know this one's a few months old but I just though I'd post an update here anyway for anyone else that comes along.
django-forms-builder has just been rewritten to do exactly what you were looking for when you originally posted this question.
You can find the new version at http://github.com/stephenmcd/django-forms-builder or http://bitbucket.org/stephenmcd/django-forms-builder
There are many alternatives, although not many of them are actively maintained:
https://www.djangopackages.com/grids/g/form-builder/
If you want to have a full control of what's happening (change fields for your needs or add new ones, add captcha or honeypot, add custom handling of form data, use form wizards or even use your forms via web REST API), use django-fobi https://pypi.python.org/pypi/django-fobi

Categories