agateblue / django-dynamic-preferences

Dynamic global and instance settings for your django project
https://django-dynamic-preferences.readthedocs.org/
BSD 3-Clause "New" or "Revised" License
347 stars 86 forks source link

FilePathField not supported? #203

Open eeintech opened 4 years ago

eeintech commented 4 years ago

Hello,

I'm trying to call a FilePathField model into the FilePreference (I also tried BasePreference) class without success, here is my code in the dynamic_preferences_registry.py:

from django.db.models import FilePathField

@global_preferences_registry.register
class Search_Results_Directory(FilePreference):
    name = 'Search_Results_Directory'
    verbose_name = 'Search Results Directory'
    default = '../search-results/'
    required = True
    # Make it a folder
    field_class = FilePathField(path=default)

This is the error I get: Screenshot_2020-01-31_13-27-17

  File "/home/francois/Desktop/KiCad/kicad-part-manager/web-app/kicad_librarian/views.py", line 15, in SettingsURL
    form = global_preference_form_builder()
  File "/home/francois/.local/lib/python3.8/site-packages/dynamic_preferences/forms.py", line 126, in global_preference_form_builder
    return preference_form_builder(GlobalPreferenceForm, preferences, **kwargs)
  File "/home/francois/.local/lib/python3.8/site-packages/dynamic_preferences/forms.py", line 107, in preference_form_builder
    f = preference.field
  File "/home/francois/.local/lib/python3.8/site-packages/dynamic_preferences/types.py", line 76, in field
    return self.setup_field()
  File "/home/francois/.local/lib/python3.8/site-packages/dynamic_preferences/types.py", line 82, in setup_field
    return field_class(**field_kwargs)
TypeError: 'FilePathField' object is not callable

Is there a workaround? I would like the user to be able to select a directory, not a file.

Thank you, Francois

agateblue commented 4 years ago

Hi @Cisco25! The field_class argument should be a FormField not a ModelField. So use django.forms.FilePathField instead of django.db.FilePathField: https://docs.djangoproject.com/en/2.2/ref/forms/fields/#filepathfield

You can specify additional arguments to the field class with field_kwargs or get_field_kwargs, as shown here: https://django-dynamic-preferences.readthedocs.io/en/latest/quickstart.html#form-fields

eeintech commented 4 years ago

Hi @EliotBerriot,

You are right, my mistake. I reread the documentation and now it's clear, sorry I'm starting with Django and there was no example on how to put everything together for the form fields so I was kind of lost. I would suggest adding a simple example like:

    field_class = forms.CharField
    field_kwargs = {
        'max_length': 255,
        'widget' : forms.TextInput(attrs={'size':60})
    }

    def get_field_kwargs(self):
        """
        Return a dict of arguments to use as parameters for the field
        class instianciation.
        """
        kwargs = self.field_kwargs.copy()
        print(f'kwargs = {kwargs}')
        kwargs.setdefault('label', self.get('verbose_name'))
        kwargs.setdefault('help_text', self.get('help_text'))
        kwargs.setdefault('widget', self.get('widget'))
        kwargs.setdefault('required', self.get('required'))
        kwargs.setdefault('initial', self.initial)
        kwargs.setdefault('validators', [])
        kwargs['validators'].append(self.validate)
        return kwargs

I also got mistaken by the name of this field (FilePathField) which I thought who let the user select a folder on his system and return the path, however, it is actually used for listing files and folders inside an already defined folder, which is not what I wanted... I'm gonna keep looking.

Thanks a bunch, Francois

agateblue commented 4 years ago

You are right, my mistake. I reread the documentation and now it's clear, sorry I'm starting with Django and there was no example on how to put everything together for the form fields so I was kind of lost. I would suggest adding a simple example like:

It's ok, that's also why we have an issue tracker :)

If you or anyone else wants to turn your snippet into an example in our documentation I'd be happy to review/merge the corresponding pull request.

Take care @Cisco25

agateblue commented 4 years ago

I also got mistaken by the name of this field (FilePathField) which I thought who let the user select a folder on his system and return the path

Regarding this specific use case, I'm not sure this is actually possible: as far as I can tell for security reasons, the web browser would never send the filesystem path to the webserver.