Django forms question - django

I want to generate a form from a model. However one of the fields in the model is a CharField, whose value is mostly "Option1" "Option2" or "Option3". If the user chooses "Other" I would like him to be able to type the value of the field.
How can I do this without having to write a whole form by hand?

I think one only way could be to build your own widget and associate that widget with that CharField on a ModelForm
Django Widgets
UPDATE
Here's a sample custom widget implementation that inherits from TextInput:
http://www.kryogenix.org/days/2008/03/28/overriding-a-single-field-in-the-django-admin-using-newforms-admin

Related

How to display a custom form with multiple widgets for a field in Django admin?

The Django docs say you can add a form to the admin UI:
class ArticleAdmin(admin.ModelAdmin):
form = MyArticleAdminForm
I want a custom editing UI for a special field in my model, where I display multiple widgets. (It's not exactly the same, but an analogy might be an old-school hex editor widget, where you want fine editing control on a big blob of information.) Perhaps I could break the multiple values into multiple database objects and use an InlineAdmin, but I have app-specific reasons to not do that.
I thought I'd use a Form object with some custom fields, but Django says it must be a ModelForm:
<class 'myapp.admin.MyAdmin'>: (admin.E016) The value of 'form' must inherit from 'BaseModelForm'.
Is it possible to display multiple widgets (basically a very custom form) for a single model value in Django admin?
EDIT: It looks like MultiWidget might work? I'm gonna look into that. Also, this question is related. That suggests I should just change the widget on the field.
The answer was to make a MultiWidget, overriding:
__init__ to set up the widgets
decompress and value_from_datadict to unpack and pack the field value
template_name to render my own template
get_context to make the context for the template

DjangoAdmin: How to keep the '+✎ ✕' buttons for a Foreign Key on when using `AutocompleteSelect` widget

I'm using the AutocompleteSelect widget for a ForeignKey field. To do this, I override the default Admin Form using the ModelForm class like this:
class ContainerModelForm(forms.ModelForm):
...
some_fk = forms.ModelChoiceField(
queryset=SomeModel.objects.all(),
widget=AutocompleteSelect(ContainerModel.some_fk.field.remote_field, admin.site)
)
However, by using this widget I lose the + ✎ ✕ buttons that are available on the Django Admin interface for a Foreign Key field by default.
What will be a good way to use AutoCompleteSelect widget but also keeping these Add/Edit/Delete buttons besides the foreign key field on the Admin UI?
Django seems to wrap widgets for ForeignKey and ManyToManyField from model regardless of the form field type / widget used.
https://github.com/django/django/blob/920448539631b52dcee53bd32a880abbc9de18bd/django/contrib/admin/options.py#L144-L175
Are you sure some_fk is an actual field in the model?
Even if it's not, you can probably achieve something similar by wrapping it the same way.

In Django Forms, how to add a filter to a SelectedMultiple control?

I'm working with Django Forms. In my model, i have a ManyToMany relationship between class X and class Y and Django shows a very annoying MultipleChoice control to edit this relationship. I would like to add a filter so editing the X object the user can filter the Y objects by name while he writes the name to finally select them
Some idea about how to do this in Django?
By default, a ManyToManyField in a Django Model will be represented by a ModelMultipleChoiceField in the ModelForm, which itself uses a SelectMultiple widget. This widget uses the default browser <select multiple="multiple"> element, which results in your "annoying" multiple choice control.
So in order to replace it, you should override the ModelMultipleChoiceField in your form to pass it your own widget (which would subclass SelectMultiple and override the template used):
my_field = forms.ModelMultipleChoiceField(queryset=Y.objects.all(), widget=MySelectMultiple)
However, many people have already done this kind of thing, so it's probably easier to use a package that has a nice multiple choice widget to your liking.
A very popular jquery module on the front-end is select2. If you want to use it, there are some django packages that already support it, popular ones are django-autocomplete-light and django-select2

django generic view update/create: update works but create raises IntegrityError

I'm using CreateView and UpdateView directely into urls.py of my application whose name is dydict. In the file forms.py I'm using ModelForm and I'm exluding a couple of fields from being shown, some of which should be set when either creating or updating. So, as mentioned in the title, update part works but create part doesn't which is obvious because required fields that I have exluded are sent empty which is not allowed in my case. So the question here is, how should I do to fill exluded fields into the file forms.py so that I don't have to override CreateView?
Thanks in advance.
Well, you have to set your required fields somewhere. If you don't want them to be shown or editable in the form, your options are to set them in the view (by using a custom subclass of CreateView) or if appropriate to your design in the save method of the model class. Or declare an appropriate default value on the field in the model.
It would also work to allow the fields into the form, but set them to use HiddenInput widgets. That's not safe against malicious input, so I wouldn't do that for purely automated fields.
You cannot exclude fields, which are set as required in the model definition. You need to define blank=True/null=True for each of these model fields.
If this doesn't solve your issue, then please show us the model and form definitions, so we know exactly what the code looks like.

Django: Correct way to extend a certain field in the admin change form with HTML?

Let's say I have a model with a field based on the ImageField class.
class Foo(models.Model):
imagefile = models.ImageField('File', upload_to='foo/%Y/%m%/%d/')
Django adds - after first upload - an input tag of type file to let me change it and a link to the image to view it.
I want this original field specific (HTML) code as is (and by no means create it myself manually) but also add other HTML/JS code, say to include a thumbnail-preview or add some AJAX-stuff. I can image a few other use cases for other fields, too.
What's the correct (say: easy/unobtrusive) way to implement something like that?
You need to write a custom widget. Look at django.forms.widgets for the code of the existing FileInput widget, which you can subclass and override the render method where necessary. You'll then just need to assign that widget for your file field in your admin form.