Comments (21)
As discussed:
- If you need to store state during a request, you can do that on the view, since it's save to do in CBVs.
- We need to document that it's not possible to save state on the modeladmin that is not allowed to endure more than request-response cycle.
- We should add in-code comments to explain the same.
from django-admin2.
@freakboy3742 and I realized we can pass to the views a default list of values/methods/properties and take out the ModelAdmin2 object.
If the user wants to add more fields, they can add them by writing them to a list, perhaps called ModelAdmin2.dataset
.
from django-admin2.
Most objects that one could potentially use to store state on have a lifetime greater than the request/response cycle.
Admin2 (as opposed to django.contrib.admin) does have an obvious place to store state (the views) that is also safe.
Thus I think documenting the issue and showing how to do it the right way (just use the view) should be enough.
from django-admin2.
It was my understanding that we added in passing the modeladmin to the view as a quick way of getting permissions up and running. Given that all of the views will be returning TemplateResponse objects we can add the permissions to the context as a wrapper function rather than in the view code itself.
from django-admin2.
I've got a branch with that deals with the template context part of the modeladmin dependency (https://github.com/AndrewIngram/django-admin2/compare/remove-modeladmin-from-view-instance). Need to think about how view-level permissions should be treated. Can someone expand on the permission object concept in issue #96? It might be the solution to this half of the problem.
from django-admin2.
I talked it out with @freakboy3742 and he suggested something similar to what is in @AndrewIngram's branch. I'll review it in the morning. 😪
from django-admin2.
@RaphaelKimmig - We'll definitely have to warn developers in the docs because even with better state handling in views we still risk them mucking around with the ModelAdmin object. Once we get the code down let's do that perfectly. Kick-butt docs are a must!
from django-admin2.
@AndrewIngram - Can you take a look at rbaf573b. It's rough and it seems to do exactly what I want:
- Copy a limited set of ModelAdmin attributes to an ImmutableAdmin object.
- We provide a default set, but the developer can override it by setting ModelAdmin2.model_admin_attributes. We do this to avoid the potential performance penalty for groups with gigantic data sets.
from django-admin2.
What will happen if a mutable object is copied to ImmutableAdmin? It seems that whilst we wouldn't be able to modify the ImmutableAdmin itself, we'd still be able to change the attribute objects, which would be references back to those on the original ModelAdmin.
from django-admin2.
I've added a comment to baf573b, but I'm not sure if that will end up getting linked to this issue.
from django-admin2.
I'm still leaning towards only passing necessary fields to the views and no longer pass the modeladmin2. It's always possible to override get_default_view_kwargs
on any modeladmin2, and it seems that at the moment we're mostly trying to engineer a solution to avoid passing a dictionary with 4 extra items in it.
from django-admin2.
This feels right to me too. Can we enumerate a list of the fields that we expect to pass to the views?
from django-admin2.
The problem with passing in lots of arguments is as follows: Since Django views only accept init arguments that are already defined as attributes, any new arguments added will force the users to admin2 to modify potentially all their view classes. This will prove to be a very unpopular with users of admin2, not to mention ourselves.
The answer is passing in a collection of attributes, either as a dictionary or a class. For this sort of thing I prefer to use classes/objects because it's consistent with the rest of the project's use of classes.
from django-admin2.
Another option is to re-evaluate whether the modeladmin object itself should be responsible for managing the permissions of all its subviews, or whether the views themselves should handle it. If these same views were being used outside the context of an admin rebuild we wouldn't think twice about using a permission mixin or decorator and being done with it, what's the special case that makes the admin different?
from django-admin2.
I have some ideas of making the permission handling a bit easier by having a new Permissions object that will have the necessary logic attached. So we only end up passing one variable into the template. I'm going to show some code of how I think this could work later today.
from django-admin2.
@AndrewIngram It's not just the permissions, it's other things to pass from the ModelAdmin object. Things like list_filters, sort_filters, fields, and much more. For example, even without the audit I think we all suspect will happen, the list of fields at https://github.com/twoscoops/django-admin2/blob/master/djadmin2/models.py#L24-L54 is too long to pass into every view declaration.
Having developers (and us) have to define 15+ arguments to make a valid Admin2 view seems a bit off. On the other hand, that's what base view classes are for, right? Hmmm... maybe that's it.
from django-admin2.
After hacking a bit on the permissions (see #96 (comment)) I more and more think that it is not really practical to keep the model_admin
out of the view.
I think if we do this, we dig ourselves a hole that will not kill us but will always be an annoyance. I still see @pydanny's concerns regarding that users might shoot their self in the foot, however I don't think it's worth the trade-off.
I for myself wouldn't even think of saving state to the model_admin
because when coding in the view itself, it is so obvious that self
is the thing that holds the state, since it already owns attributes like self.request
, self.object
, self.queryset
, etc...
And the view has access to so many more things that the user can use to run amok with if he really wants to. Like the self.model
which will be available from the view as well.
from django-admin2.
The problem with providing a modifiable model_admin in the view is that while @gregmuellegger (or @AndrewIngram, @inglesp, @audreyr, etc) wouldn't do it, developers with less experience (@pydanny 😉) might. In fact, the documentation for modifying state in django.contrib.admin.ModelAdmin
is not easily discoverable.
Hence why a simple wrapper object, perhaps better than the simple one I found, would be ideal.
from django-admin2.
The view already holds a few objects that are not immutable and by this are also in danger to get state attached by the user. But django doesn't do anything about it either.
Some examples:
View.model
View.paginator_class
View.response_class
View.queryset
I know that these examples are mostly classes and not instantiated objects. But I think my argument is still valid 😉 The point I'm trying to make is that why should we protect the user from doing:
class MyView(Admin2View, ...):
def get(self):
# saving state here to the model_admin instance
self.model_admin.request = self.request
... if the user is still able to do the following:
class MyView(Admin2View, ...):
def get(self):
# saving state here to the model class
self.model.request = self.request
Please don't be offended, I really try to argue with all admin2 users in mind, not just me. If @pydanny keeps with his reasons against passing the model_admin
directly, I will stop bike shedding ofcourse 😉
from django-admin2.
I agree. To me this feels like a solution looking for a problem. Most objects
(more or less everything but the view and it's parameters) have a life-cycle
that is longer than the request-response cycle and thus should not be used to
store state for views.
I do agree that with django.contrib.admin there is a problem with state.
The old admin is a class based view yet you mustn't store state on self
because it lives longer than a single request/response cycle.
There, a view is a, and uses, dozens of methods on the ModelAdmin instance to
create a response and there are several places where methods can not be
simply overriden to provide a certain functionality because they do not have
access to some of the view's state.
As a python developer it seems natural to put state that is shared between
methods into instance variables. Now we have the unfortunate situation of there
being an obvious way to do something yet that being the wrong way.
In admin2 we do not suffer the same problem because we use Django's class based
views for most functionality. When a developer wants to customize a view
beyond settings basic variables the default approach will be to subclass the
respective admin view. Here they can use the view instance to store state. This
is the intuitive way of doing it and this is the way it is going to be
documented. So in the admin2 scenario we have an obvious way of doing things
that is also the correct way.
from django-admin2.
We know that saving to the model_admin
object is dangerous because @freakboy3742 and the divio team both reported it as an issue. On the other hand, @gregmuellegger pointed out that developers can save to the model
class and it's potentially dangerous. @RaphaelKimmig states that we should encourage developers to save state to the view since that's what should be happening, that it's obvious, and it's the correct way.
However, one thing we need to consider is that we are creating an extensible, adaptable version of the admin. Developers are going to get creative and 'experts' are going to advocate monkeypatching things without thinking about problems down the road (take a look at some of the advice for hacking the User model to see what I mean). While we are all consenting adults, there is something to be said about not letter developers dig deep holes for themselves and their projects.
For example, did you know I'm known for adding attributes and methods on model classes on the fly? Works fine in normal architectures, but in django-admin2 it might be a problem.
Dictator's Determination
I'm pulling out the dictator card here.
However, please read on and don't be upset even though I'm mandating we're going forward with locking down the model_admin
class.
Yes, we are going to do is constrain the model_admin
class and make what is passed into the views immutable using something better than my simple hack. If possible, we'll also do this to the model classes, but that might have weird repercussions that we won't understand until we finish documenting django.db.models.Model._meta
.
Please consider that if we lock things down now, and it turns out that it's a good thing, then we all win. If it turns out to be a hindrance, our documentation explicitly says what not to do, and performance analysis says the lockdown slows down the app, then we can 'liberate' the model_admin. Again, we win. 😄
Here's the scenario I considered when making this decision: We open things up right now and realize later it was a huge mistake. Now we have to lock things down and we SHATTER backwards compatibility with whatever hacks and monkeypatches were created against django-admin2. Rants about it go viral and people misunderstand whatever we are fixing. It's a nightmare scenario, but these sorts of viral explosions are know to happen.
So again, the lockdown continues and we'll be exploring better Immutable/Frozen class objects.
from django-admin2.
Related Issues (20)
- Django 1.8 issue HOT 3
- Django 1.8 issues HOT 1
- Add 'django.template.context_processors.static', to context_processors
- Add Django 1.9 compatability HOT 23
- Enhancement: Removing dependancy that matter only in theme HOT 2
- Deregister last app model does not delete the app
- fix test on travis HOT 2
- fix test on travis HOT 1
- Add material theme for admin2
- 0.7.0 release HOT 4
- move test runner and tests to py.test
- move views to django-vanilla-views
- Jinja2 template engine support
- djangocircus.com domain expired HOT 1
- New Transifex maintainer wanted HOT 5
- Add django 1.11 LTS and 2.0 support and remove EOL versions. HOT 2
- Plans for future release Django 2.x? HOT 2
- consider using https://github.com/ilblackdragon/django-themes
- No update since roughly one year. State of the project?1 HOT 4
- ERROR: django-admin2 0.7.1 has requirement django-filter==1.0.0, but you'll have django-filter 2.3.0 which is incompatible. HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from django-admin2.