How to force/warn way devs treat class/django model
We have a Django
project and I came across this problem multiple times this year.
I will simplify the example:
class MyModel(Model):
my_attr = ....
...
def get_my_attr_safe():
if not self.my_attr:
return somecalculation()
return self.my_attr
I want to force developers to use get_my_attr_safe()
instead of my_attr
.
It's a huge and complicated model.
My idea was to somehow override __getattribute__
and raise Exception if it's called directly but I don't think this would work. Moreover, Django
, of course needs to call sometimes ModelFields
directly so I can't just do it this way.
I want to either raise Exception
or make sure they will get the information that they have to use the method
if possible.
For example I need them to use the method everywhere in templates:
{{ obj.get_my_attr_safe }}
instead of
{{ obj.my_attr }}
The solution doesn't have to be Python
ic, maybe there is a way to do this using PyCharm
only. It would be enough.
python django pycharm
add a comment |
We have a Django
project and I came across this problem multiple times this year.
I will simplify the example:
class MyModel(Model):
my_attr = ....
...
def get_my_attr_safe():
if not self.my_attr:
return somecalculation()
return self.my_attr
I want to force developers to use get_my_attr_safe()
instead of my_attr
.
It's a huge and complicated model.
My idea was to somehow override __getattribute__
and raise Exception if it's called directly but I don't think this would work. Moreover, Django
, of course needs to call sometimes ModelFields
directly so I can't just do it this way.
I want to either raise Exception
or make sure they will get the information that they have to use the method
if possible.
For example I need them to use the method everywhere in templates:
{{ obj.get_my_attr_safe }}
instead of
{{ obj.my_attr }}
The solution doesn't have to be Python
ic, maybe there is a way to do this using PyCharm
only. It would be enough.
python django pycharm
1
This seems to be against Python's Zen. As we all know, Python doesn't even have a mandatory scope restriction such asprivate
,protect
or something else. The reason is Python believes in the developers They can do the right things. So with the same Zen, I think you should provide enough document for your users, and notice them that if you don't use it in this way, what will happen etc.
– Sraw
Nov 21 '18 at 17:53
Good use of PR review can be helpful here :) It seems to me it will be overkill to override__getattribute__
or any kind of hack, for achieving something simple.
– ruddra
Nov 21 '18 at 18:38
add a comment |
We have a Django
project and I came across this problem multiple times this year.
I will simplify the example:
class MyModel(Model):
my_attr = ....
...
def get_my_attr_safe():
if not self.my_attr:
return somecalculation()
return self.my_attr
I want to force developers to use get_my_attr_safe()
instead of my_attr
.
It's a huge and complicated model.
My idea was to somehow override __getattribute__
and raise Exception if it's called directly but I don't think this would work. Moreover, Django
, of course needs to call sometimes ModelFields
directly so I can't just do it this way.
I want to either raise Exception
or make sure they will get the information that they have to use the method
if possible.
For example I need them to use the method everywhere in templates:
{{ obj.get_my_attr_safe }}
instead of
{{ obj.my_attr }}
The solution doesn't have to be Python
ic, maybe there is a way to do this using PyCharm
only. It would be enough.
python django pycharm
We have a Django
project and I came across this problem multiple times this year.
I will simplify the example:
class MyModel(Model):
my_attr = ....
...
def get_my_attr_safe():
if not self.my_attr:
return somecalculation()
return self.my_attr
I want to force developers to use get_my_attr_safe()
instead of my_attr
.
It's a huge and complicated model.
My idea was to somehow override __getattribute__
and raise Exception if it's called directly but I don't think this would work. Moreover, Django
, of course needs to call sometimes ModelFields
directly so I can't just do it this way.
I want to either raise Exception
or make sure they will get the information that they have to use the method
if possible.
For example I need them to use the method everywhere in templates:
{{ obj.get_my_attr_safe }}
instead of
{{ obj.my_attr }}
The solution doesn't have to be Python
ic, maybe there is a way to do this using PyCharm
only. It would be enough.
python django pycharm
python django pycharm
edited Nov 21 '18 at 17:53
Milano
asked Nov 21 '18 at 17:24
MilanoMilano
4,4621443125
4,4621443125
1
This seems to be against Python's Zen. As we all know, Python doesn't even have a mandatory scope restriction such asprivate
,protect
or something else. The reason is Python believes in the developers They can do the right things. So with the same Zen, I think you should provide enough document for your users, and notice them that if you don't use it in this way, what will happen etc.
– Sraw
Nov 21 '18 at 17:53
Good use of PR review can be helpful here :) It seems to me it will be overkill to override__getattribute__
or any kind of hack, for achieving something simple.
– ruddra
Nov 21 '18 at 18:38
add a comment |
1
This seems to be against Python's Zen. As we all know, Python doesn't even have a mandatory scope restriction such asprivate
,protect
or something else. The reason is Python believes in the developers They can do the right things. So with the same Zen, I think you should provide enough document for your users, and notice them that if you don't use it in this way, what will happen etc.
– Sraw
Nov 21 '18 at 17:53
Good use of PR review can be helpful here :) It seems to me it will be overkill to override__getattribute__
or any kind of hack, for achieving something simple.
– ruddra
Nov 21 '18 at 18:38
1
1
This seems to be against Python's Zen. As we all know, Python doesn't even have a mandatory scope restriction such as
private
, protect
or something else. The reason is Python believes in the developers They can do the right things. So with the same Zen, I think you should provide enough document for your users, and notice them that if you don't use it in this way, what will happen etc.– Sraw
Nov 21 '18 at 17:53
This seems to be against Python's Zen. As we all know, Python doesn't even have a mandatory scope restriction such as
private
, protect
or something else. The reason is Python believes in the developers They can do the right things. So with the same Zen, I think you should provide enough document for your users, and notice them that if you don't use it in this way, what will happen etc.– Sraw
Nov 21 '18 at 17:53
Good use of PR review can be helpful here :) It seems to me it will be overkill to override
__getattribute__
or any kind of hack, for achieving something simple.– ruddra
Nov 21 '18 at 18:38
Good use of PR review can be helpful here :) It seems to me it will be overkill to override
__getattribute__
or any kind of hack, for achieving something simple.– ruddra
Nov 21 '18 at 18:38
add a comment |
2 Answers
2
active
oldest
votes
The use of underscores might help here:
class MyModel(Model):
_my_attr = None
def get_my_attr_safe(self):
if self._my_attr is None:
self._my_attr = somecalculation()
return self._my_attr
my_attr = property(get_my_attr_safe)
Taken from this answer
add a comment |
I would not recommend overriding __getattr__
or touch anything in Model
class. This is the core of Django, if you do something, you might not know where the next bug will pop up. Rather than that, I think its better to use a wrapper around it to get the restrictions there. For example:
class YourModelWrapper(object):
model_object = None
restricted_fields = ['some', 'fields']
def __init__(self, model_object):
self.model_object = model_object
def __getattr__(self, name):
if name is not in self.restricted_fields:
return getattr(self.model_object, name)
raise AttributeError("Use get_{}_safe() method instead".format(name)
# Usage
your_model_wrapper_obj = YourModelWrapper(YourModel.objects.first())
your_model_wrapper_obj.my_attr # will raise exception
your_model_wrapper_obj.get_my_attr_safe() # will return the values
FYI it will be a hassle to use this instead of actual model because there is lots of thing missing from this wrapper like queryset support. But there is a good side as well. You have said your model is very complicated, so using a wrapper might help to put some complexities from Model to Wrapper, or use it like a service.
add a comment |
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53417552%2fhow-to-force-warn-way-devs-treat-class-django-model%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
The use of underscores might help here:
class MyModel(Model):
_my_attr = None
def get_my_attr_safe(self):
if self._my_attr is None:
self._my_attr = somecalculation()
return self._my_attr
my_attr = property(get_my_attr_safe)
Taken from this answer
add a comment |
The use of underscores might help here:
class MyModel(Model):
_my_attr = None
def get_my_attr_safe(self):
if self._my_attr is None:
self._my_attr = somecalculation()
return self._my_attr
my_attr = property(get_my_attr_safe)
Taken from this answer
add a comment |
The use of underscores might help here:
class MyModel(Model):
_my_attr = None
def get_my_attr_safe(self):
if self._my_attr is None:
self._my_attr = somecalculation()
return self._my_attr
my_attr = property(get_my_attr_safe)
Taken from this answer
The use of underscores might help here:
class MyModel(Model):
_my_attr = None
def get_my_attr_safe(self):
if self._my_attr is None:
self._my_attr = somecalculation()
return self._my_attr
my_attr = property(get_my_attr_safe)
Taken from this answer
answered Nov 21 '18 at 18:07
Bott0610Bott0610
618412
618412
add a comment |
add a comment |
I would not recommend overriding __getattr__
or touch anything in Model
class. This is the core of Django, if you do something, you might not know where the next bug will pop up. Rather than that, I think its better to use a wrapper around it to get the restrictions there. For example:
class YourModelWrapper(object):
model_object = None
restricted_fields = ['some', 'fields']
def __init__(self, model_object):
self.model_object = model_object
def __getattr__(self, name):
if name is not in self.restricted_fields:
return getattr(self.model_object, name)
raise AttributeError("Use get_{}_safe() method instead".format(name)
# Usage
your_model_wrapper_obj = YourModelWrapper(YourModel.objects.first())
your_model_wrapper_obj.my_attr # will raise exception
your_model_wrapper_obj.get_my_attr_safe() # will return the values
FYI it will be a hassle to use this instead of actual model because there is lots of thing missing from this wrapper like queryset support. But there is a good side as well. You have said your model is very complicated, so using a wrapper might help to put some complexities from Model to Wrapper, or use it like a service.
add a comment |
I would not recommend overriding __getattr__
or touch anything in Model
class. This is the core of Django, if you do something, you might not know where the next bug will pop up. Rather than that, I think its better to use a wrapper around it to get the restrictions there. For example:
class YourModelWrapper(object):
model_object = None
restricted_fields = ['some', 'fields']
def __init__(self, model_object):
self.model_object = model_object
def __getattr__(self, name):
if name is not in self.restricted_fields:
return getattr(self.model_object, name)
raise AttributeError("Use get_{}_safe() method instead".format(name)
# Usage
your_model_wrapper_obj = YourModelWrapper(YourModel.objects.first())
your_model_wrapper_obj.my_attr # will raise exception
your_model_wrapper_obj.get_my_attr_safe() # will return the values
FYI it will be a hassle to use this instead of actual model because there is lots of thing missing from this wrapper like queryset support. But there is a good side as well. You have said your model is very complicated, so using a wrapper might help to put some complexities from Model to Wrapper, or use it like a service.
add a comment |
I would not recommend overriding __getattr__
or touch anything in Model
class. This is the core of Django, if you do something, you might not know where the next bug will pop up. Rather than that, I think its better to use a wrapper around it to get the restrictions there. For example:
class YourModelWrapper(object):
model_object = None
restricted_fields = ['some', 'fields']
def __init__(self, model_object):
self.model_object = model_object
def __getattr__(self, name):
if name is not in self.restricted_fields:
return getattr(self.model_object, name)
raise AttributeError("Use get_{}_safe() method instead".format(name)
# Usage
your_model_wrapper_obj = YourModelWrapper(YourModel.objects.first())
your_model_wrapper_obj.my_attr # will raise exception
your_model_wrapper_obj.get_my_attr_safe() # will return the values
FYI it will be a hassle to use this instead of actual model because there is lots of thing missing from this wrapper like queryset support. But there is a good side as well. You have said your model is very complicated, so using a wrapper might help to put some complexities from Model to Wrapper, or use it like a service.
I would not recommend overriding __getattr__
or touch anything in Model
class. This is the core of Django, if you do something, you might not know where the next bug will pop up. Rather than that, I think its better to use a wrapper around it to get the restrictions there. For example:
class YourModelWrapper(object):
model_object = None
restricted_fields = ['some', 'fields']
def __init__(self, model_object):
self.model_object = model_object
def __getattr__(self, name):
if name is not in self.restricted_fields:
return getattr(self.model_object, name)
raise AttributeError("Use get_{}_safe() method instead".format(name)
# Usage
your_model_wrapper_obj = YourModelWrapper(YourModel.objects.first())
your_model_wrapper_obj.my_attr # will raise exception
your_model_wrapper_obj.get_my_attr_safe() # will return the values
FYI it will be a hassle to use this instead of actual model because there is lots of thing missing from this wrapper like queryset support. But there is a good side as well. You have said your model is very complicated, so using a wrapper might help to put some complexities from Model to Wrapper, or use it like a service.
edited Nov 21 '18 at 20:39
answered Nov 21 '18 at 19:35
ruddraruddra
16.1k32951
16.1k32951
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53417552%2fhow-to-force-warn-way-devs-treat-class-django-model%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
This seems to be against Python's Zen. As we all know, Python doesn't even have a mandatory scope restriction such as
private
,protect
or something else. The reason is Python believes in the developers They can do the right things. So with the same Zen, I think you should provide enough document for your users, and notice them that if you don't use it in this way, what will happen etc.– Sraw
Nov 21 '18 at 17:53
Good use of PR review can be helpful here :) It seems to me it will be overkill to override
__getattribute__
or any kind of hack, for achieving something simple.– ruddra
Nov 21 '18 at 18:38