agateblue/django-dynamic-preferences

FilePathField not supported?

eeintech opened this issue · 4 comments

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

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

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

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

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.