-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create CallableSetting #49
Comments
Still using checkers 😉? They were deprecated in a previous PR introducing Django-style validators. Unfortunately, for this use-case a validator would not be enough, since they operate on the raw value and not the transformed one. I think if we generalize the use-case, we would need to add a way to perform validation on the transformed value. I'd like your opinion on this, as well as @ziima's. About For example, with:
...then |
Yeah, that's what I thought as well. The current code in Django 2.2 is a little bit different, but the property you describe still stands. I have never used ObjectSetting for anything that |
I usually imagine someone using classes as enums, like I did here in another project: # callbacks.py
class STATE:
class SEARCH:
PATTERN, SELECT = range(2)
class GRANT:
USER, PRIVILEGE = range(2)
REVOKE = GRANT The setting could then be Anyway, I agree that using a Django battle-tested function could be better than using custom code, but if the main concern is avoiding duplicated code (when adding a new CallableSetting), then we can also move the few lines in a utility function called To go back to the CallableSetting. We could do this indeed: class CallableSetting(ObjectSetting):
def validate(self, value):
transformed_value = self.transform(value)
if not callable(transformed_value):
raise ValueError('{} must be a dotted path to callable'.format(self.full_name)) But now if the user wants to add even more custom validation, they will have to call |
That's actually pretty good use case, thank you! I guess we can keep it the way it is.
I think that calling |
And do we actually want to run validation on a raw value instead of the final one? Django objects (models, forms) validate final values, not the raw ones. |
Yeah, that might be even better solution. |
Interesting point. Let say we validate only once transformed. For settings which are not transformed, the behavior stays the same. For the ones which are transformed, the first thing I dislike is that we will run the Usually the transformation will not be heavy, but if it is, it will slow down the startup (maybe I'm a bit too paranoid about perf though). Maybe I'm going too far but we also have to consider it's possible that the transformation has side-effects, which could cause issues if ran twice or more. I'm getting a bit crazy, but let say you have a setting, which when transformed is creating a file or launching a program listening to a port or something, and then return the file path or the PID of the program. It could pass the initial check, and fail when accessing the setting the second time. A solution to this double transformation would be to cache the transformed value inside of the setting itself, as long as the raw value is the same ( Also maybe sometimes you really want to validate the raw value and not the transformed one, because if the raw value is OK, you know the transformed one will be too (you are the one writing the transform function after all). So the question is:
Then how should this be implemented?
Sorry for the long text and waiting for your thoughts on this 🙂 |
Well, if we'll have a transformation cache, we can just call Are you concerned about running some validators before the |
Yeah okay. Let's create a I think we should name it For posterity: I thought of a third way for pre/post validation: by adding a parameter to the validators constructor, something like |
I should get to the PR before the end of this week 😉. |
In several of my projects, I needed to create callable setting, i.e. string setting that would contain dotted path to a callable. There is one example of how I implemented it:
I just noticed that ObjectSetting can contain path to a callable as well. However, it does not have custom validation checking whether path leads to a callable.
Also, ObjectSetting uses its own import machinery, that could might be replaced by
django.utils.module_loading.import_string
(however, the functionality is a little bit different, so it might be a breaking change).I propose creating
CallableSetting
as a subclass ofObjectSetting
, containing specific check whether the value points to a callable. If you agree, I will be happy to submit a pull request.We can also discuss replacing
ObjectSetting.transform
bydjango.utils.module_loading.import_string
(possibly a breaking change).The text was updated successfully, but these errors were encountered: