I want to create a SelectField that offers suggestions but still allow the user to enter something else.
class MyForm(Form):
username = wtf.StringField()
title = wtf.SelectField('Job title', choices=['Owner', 'Manager'], validate_choices=False)
WTF documentation suggests that setting validate_choices to False allows this:
Note the validate_choice parameter - by setting this to False we are telling the SelectField to skip the choice validation step and instead to accept any inputted choice without checking to see if it was one of the given choices.
But, no data entry or modification is possible with above. Is this possible or do I need another 'manual entry' field?
Or, is there perhaps a way to show my suggestions in a StringField using JS similar to the way the browsers offer autocomplete suggestions for addresses etc?
I'm not aware of any way to do this. It seems you and I are in a similar position. However, I did have an idea I wanted to share that could work for you.
Many forms will have a dropdown with a value "Other" and if you select "Other" there is another empty box that appears for you to type in. You could implement this pretty easily in wtforms. Alternatively you could have the extra box always display and just do a check that they did indeed select "Other" if they have a custom input.
I have opened an issue, but they are not planning to add this feature.
Based on this, we could, but it is not a pure python implementation
Related
I have a model with this field:
exercise = models.CharField(max_length=25, choices=EXERCISES_CHOICES)
but the list of exercises is VERY long, when I use it in the admin interface it occupies all the length of the page, is there a way to display in subitems?
I have a similar problem, but mine is not a list of choices - instead it is a foreign key field and the default in the Admin is also to display the entire list of available values in an option menu; as the database fills, this will probably be unusable. My plan is to create a custom Admin widget which uses a text input instead of an option menu, and use autocomplete to help fill in the value. I have not yet implemented it - I've started looking for autocomplete packages. Maybe once I decide on one, I'll come back and post an update.
P.S. It seems to me this would be a common problem and should already have been solved. Why can't I find anything out there?
---- EDIT ----
Apparently this has been solved! According to its documentation, the "django-extensions" package includes a "ForeignKeyAutocompleteAdmin" class. Hurray! See here:
http://pythonhosted.org/django-extensions/admin_extensions.html
https://pypi.python.org/pypi/django-extensions
Disclaimer: I haven't tried it yet (but I intend to!)
Before I start on this project I want make sure what I am proposing is feasible. There is an unusual requirements I have to satisfy.
The model and formModel fields have to support a comment field on every field. I would like to be able to access them by object.field and object.field.comment. At first glance, this looks like I should have a separate type of comment and then somehow link it to correct field but is there a way to create a custom modelField that stores data in more then one database field from one or more form inputs? I would think there would have to be a custom widget to support this too?
If anyone has any ideas or examples of anything like this please respond.
I think this is the answer to my question. I have not tried it yet, but from the description it looks like what I need. https://docs.djangoproject.com/en/dev/ref/forms/widgets/#multiwidget
I am writing a Django application and using the built-in ORM. I would like to create functionality to provide a form but the template for that form needs to be built on admin side of the application and can change over time.
For instance, initially they have a form that asks for first name, last name but later if they decide to add birthday field admin should be able to go to this template page add birthrate as new field and on client side, users start seeing it. Is there anything already in place that can be used? I was thinking of using something like this but decided to check here and see if there is something better available.
Is it this what your are looking for?
I have never heard about any library for that, because you have pretty much different approaches to handle that!, but check the link, he is explaining better those approaches.
What is the best way to conditionally display a field in the admin depending upon the values of other fields?
In particular I'm thinking about the add_form and change_form. Whenever a certain choice is selected I'd like to hide or disable some fields.
I'm thinking that this might require a javascript solution, but am wondering if there is a better (i.e. builtin) way to do this.
Bernhard is right. You might be able to hack the admin view and template to conditionally show/not show widgets for a field, but if you want to do it dynamically based on user behaviors in the admin, you'll be using javascript.
It's not so terrible, though. At least the Django admin templates have model- and instance-specific ids to give you granular control over your show/hide behavior.
My answer may sound esoteric - but I suspect the design direction you may be taking could benefit from some reconsideration. When an interface requires that much TLC to resort to AJAX to make for a superior UX I am inclined to not use Admin interface for that.
My personal view of the Admin interface of Django is that it is a great freebie that gives me an instant CRUD view at a basic level. I would refrain from piggy backing on it for those who need a more user friendly interface (even if some of these users are handling admin functions). You will acquire technical debt in trying to do these type of Ajax UI/UX and complex form validations using the Admin interface.
I think you should be able to create your own ModelForm and specify that the admin uses that (https://docs.djangoproject.com/en/1.7/ref/contrib/admin/#django.contrib.admin.ModelAdmin.form).
Use the _init__() method of the form to selectively display the fields.
I will give it a try and update this answer if it works.
(Actually re-reading the question, it depends. If "values of other fields" is set before the page is loaded, this idea should work. If you want an instant response - click one field and another appears/disappears, yes you will need JavaScript).
So let's say at the last minute (in the view) I decide I want to specify a default for a field and make it hidden, like so:
form.fields['coconut'] = forms.ModelChoiceField(
label="",
widget=forms.HiddenInput(),
queryset=swallow.coconuts.all(),
initial=some_particular_coconut,
)
My question is this: Do I really need to specify queryset here? I mean, I already know, from initial, exactly which coconut I'm talking about. Why do I also need to specify that the universe of available coconuts is the set of coconuts which this particular swallow carried (by the husk)?
Is there a way I can refrain from specifying queryset? Simply omitting causes django to raise TypeError.
If indeed it is required, isn't this a bit damp?
I think is good that stackoverflow answers point to the 'right' way to do things, but increasingly the original question goes unanswered because the user was trying to do the wrong thing.
So to answer this question directly this is what you can do:
form.fields['coconut'] = forms.ModelChoiceField(label="", widget=forms.HiddenInput(attrs={'value':some_particular_coconut}), queryset=swallow.coconuts.all())
Notice the named argument passed to HiddenInput, its super hackish but its a direct answer to the original question.
The problem is that you're trying to set up a hidden ModelChoiceField. In order to have a Choice (dropdown, traditionally) it needs to know its Choices - this is why you give a queryset.
But you're not trying to give the user a choice, right? It's a hidden input, and you're setting it from the server (so it gets POSTed back, presumably).
My suggestion is to try to find a way around using the hidden input at all. I find them a bit hacky. But otherwise, why not just specify a text field with some_particular_coconut.id, and hide that? The model's only wrapping that id anyway.
The reason django requires a queryset is because when you render the field to the page, django only sends the id. when it comes back, it needs knowlege of the queryset in order to re-inflate that object.
if you already know the queryset at form creation time, why not simply specify form.fields['coconut'].initial = some_particular_coconut in your view and leave the rest of the definition in your forms.py?
If you find that you only really need to send the id anyway (you don't have to re-inflate to an object at your end), why not send it in a char field?