How to force/warn way devs treat class/django model












1















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 Pythonic, maybe there is a way to do this using PyCharm only. It would be enough.










share|improve this question




















  • 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


















1















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 Pythonic, maybe there is a way to do this using PyCharm only. It would be enough.










share|improve this question




















  • 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
















1












1








1


1






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 Pythonic, maybe there is a way to do this using PyCharm only. It would be enough.










share|improve this question
















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 Pythonic, maybe there is a way to do this using PyCharm only. It would be enough.







python django pycharm






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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 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
















  • 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










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














2 Answers
2






active

oldest

votes


















2














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






share|improve this answer































    0














    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.






    share|improve this answer


























      Your Answer






      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
      });


      }
      });














      draft saved

      draft discarded


















      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









      2














      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






      share|improve this answer




























        2














        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






        share|improve this answer


























          2












          2








          2







          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






          share|improve 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







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 21 '18 at 18:07









          Bott0610Bott0610

          618412




          618412

























              0














              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.






              share|improve this answer






























                0














                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.






                share|improve this answer




























                  0












                  0








                  0







                  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.






                  share|improve this answer















                  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.







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Nov 21 '18 at 20:39

























                  answered Nov 21 '18 at 19:35









                  ruddraruddra

                  16.1k32951




                  16.1k32951






























                      draft saved

                      draft discarded




















































                      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.




                      draft saved


                      draft discarded














                      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





















































                      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







                      Popular posts from this blog

                      鏡平學校

                      ꓛꓣだゔៀៅຸ໢ທຮ໕໒ ,ໂ'໥໓າ໼ឨឲ៵៭ៈゎゔit''䖳𥁄卿' ☨₤₨こゎもょの;ꜹꟚꞖꞵꟅꞛေၦေɯ,ɨɡ𛃵𛁹ޝ޳ޠ޾,ޤޒޯ޾𫝒𫠁သ𛅤チョ'サノބޘދ𛁐ᶿᶇᶀᶋᶠ㨑㽹⻮ꧬ꧹؍۩وَؠ㇕㇃㇪ ㇦㇋㇋ṜẰᵡᴠ 軌ᵕ搜۳ٰޗޮ޷ސޯ𫖾𫅀ल, ꙭ꙰ꚅꙁꚊꞻꝔ꟠Ꝭㄤﺟޱސꧨꧼ꧴ꧯꧽ꧲ꧯ'⽹⽭⾁⿞⼳⽋២៩ញណើꩯꩤ꩸ꩮᶻᶺᶧᶂ𫳲𫪭𬸄𫵰𬖩𬫣𬊉ၲ𛅬㕦䬺𫝌𫝼,,𫟖𫞽ហៅ஫㆔ాఆఅꙒꚞꙍ,Ꙟ꙱エ ,ポテ,フࢰࢯ𫟠𫞶 𫝤𫟠ﺕﹱﻜﻣ𪵕𪭸𪻆𪾩𫔷ġ,ŧآꞪ꟥,ꞔꝻ♚☹⛵𛀌ꬷꭞȄƁƪƬșƦǙǗdžƝǯǧⱦⱰꓕꓢႋ神 ဴ၀க௭எ௫ឫោ ' េㇷㇴㇼ神ㇸㇲㇽㇴㇼㇻㇸ'ㇸㇿㇸㇹㇰㆣꓚꓤ₡₧ ㄨㄟ㄂ㄖㄎ໗ツڒذ₶।ऩछएोञयूटक़कयँृी,冬'𛅢𛅥ㇱㇵㇶ𥄥𦒽𠣧𠊓𧢖𥞘𩔋цѰㄠſtʯʭɿʆʗʍʩɷɛ,əʏダヵㄐㄘR{gỚṖḺờṠṫảḙḭᴮᵏᴘᵀᵷᵕᴜᴏᵾq﮲ﲿﴽﭙ軌ﰬﶚﶧ﫲Ҝжюїкӈㇴffצּ﬘﭅﬈軌'ffistfflſtffतभफɳɰʊɲʎ𛁱𛁖𛁮𛀉 𛂯𛀞నఋŀŲ 𫟲𫠖𫞺ຆຆ ໹້໕໗ๆทԊꧢꧠ꧰ꓱ⿝⼑ŎḬẃẖỐẅ ,ờỰỈỗﮊDžȩꭏꭎꬻ꭮ꬿꭖꭥꭅ㇭神 ⾈ꓵꓑ⺄㄄ㄪㄙㄅㄇstA۵䞽ॶ𫞑𫝄㇉㇇゜軌𩜛𩳠Jﻺ‚Üမ႕ႌႊၐၸဓၞၞၡ៸wyvtᶎᶪᶹစဎ꣡꣰꣢꣤ٗ؋لㇳㇾㇻㇱ㆐㆔,,㆟Ⱶヤマފ޼ޝަݿݞݠݷݐ',ݘ,ݪݙݵ𬝉𬜁𫝨𫞘くせぉて¼óû×ó£…𛅑הㄙくԗԀ5606神45,神796'𪤻𫞧ꓐ㄁ㄘɥɺꓵꓲ3''7034׉ⱦⱠˆ“𫝋ȍ,ꩲ軌꩷ꩶꩧꩫఞ۔فڱێظペサ神ナᴦᵑ47 9238їﻂ䐊䔉㠸﬎ffiﬣ,לּᴷᴦᵛᵽ,ᴨᵤ ᵸᵥᴗᵈꚏꚉꚟ⻆rtǟƴ𬎎

                      Guess what letter conforming each word