howto add custom form into django administrator page inlines - django

Can I get a form into Django Administrator page, that I have defined in forms.py?
Can I also get this form into Model inlines of Django Administrator page ?
To be clear, this is what I call inline:
class AnswerInline(admin.StackedInline):
...

Yeah, it's a bit complicated but the docs are actually clear here:
InlineModelAdmin.form
The value for form defaults to ModelForm. This is what is passed through to
inlineformset_factory when creating the formset for this inline.
So create your form class and then refer to it in the inline, like so:
class MyForm(forms.ModelForm):
…
class AnswerInLine(admin.StackedInline):
form = MyForm

Related

Is it possible to allow to create objects from the list_display view of the django admin site?

I have a model with fields name, roll_no, birth_date
I am using the django admin's list display and list editable to have these fields displayed and edited in a list format in a single page. However, to add a new entry I have to go to the create_form page.
Is it possible to simply add new objects from the list_display page itself?
Unfortunately this feature is not available out-of-the box in the Django admin like the ModelAdmin.list_editable feature.
I'm curious to see if there are other shortcuts, but at the moment the only way I see is to customize the formset like descibed in the official Docs:
from django import forms
class MyForm(forms.ModelForm):
# customize your 'extra' forms here
class MyModelAdmin(admin.ModelAdmin):
def get_changelist_form(self, request, **kwargs):
return MyForm
And finally manually extend the changelist form template of the admin. To override a Django admin template, please follow the intructions in the Official Docs here. The template to be customized is the following folder:
.../django/contrib/admin/templates/admin/change_list.html
and you probably need to override the {% block result_list %} in that file.
NB: the customization of an admin template can be very tricky. Consider to use a CMS (like DjangoCMS) if you need to extend the user experience. The idea behind the Django admin is to make your life easier with an out-of-the-box interface for CRUDs on your DB. IMHO try to avoid complex customizations of the Django Admin if not strictly needed.

What are form factories and when should they be used?

Would someone like to attempt a succinct explanation of what a form_factory, or a modelform_factory is in relation to a form / modelform?
Why use a factory?
Is there an official technical definition for a
factory method?
The modelform_factory method is a method that returns a ModelForm class. Here's an example of why it's useful.
If you have a simple view that uses a form for a single model, then there is no need for a factory, you can simply define the form:
class ProductForm(forms.ModelForm):
class Meta:
model = Product
def add_product_view(request):
form = ProductForm()
...
However, if your view needs to handle multiple models, then you might not want to have to define a form class for every model. The modelform_factory lets you create the form class dynamically.
apps.get_model('newapp', 'mymodel')
def add_model_view(request, model_name):
Model = apps.get_model('myapp', model_name)
Form = modelform_factory(Model)
The Django admin uses modelform_factory to generate model form classes dynamically. This means you don't need to define a model form every time you register a model in the Django admin.

Create multiple objects in django admin at once

For example, I have a Post model:
Class Post(models.Model):
title = models.Charfield(max_length=200)
# other fields
I wonder is there a way to create multiple posts at once in admin. In other words, I need a formset instead of single form on post creation page.
I've heard recently about a django app that exactly does this job. It's called django-bulk-admin and enables bulk add/update in the admin.
Possibly, the best way to do exactly what you want is extend the ModelAdmin class, because it has no formsets on it, except for those used on InlineFormsets.
After that you could customize the admin change_form template, to include your formsets
The quick-and-dirty way to do it using admin is wrap your Post model as an inline formset of another modeladmin and add the extra option to it.

Change default widgets of Django to custom ones

My usecase: I want to use a different DateInput. But I want to reduce code duplication. I want all forms, which don't explicitly want a different DateInput widget, to use my custom widget.
Any change to solve this without monkey patching?
Example
models.py:
class MyModel(models.Model):
date=models.DateField()
forms.py:
class MyForm(forms.ModelForm):
class Meta:
model=MyModel
The above code should use my custom widget. I don't want to change the above models.py and forms.py, since there are many.
Unfortunately, I don't think you can get this working with your exact code listed above.
Without hacking django, essentially there are 2 parts to this. The first is creating a custom form field, and the second is defaulting your custom model field to your newly created form field.
To create your custom Form Field, you could override the existing django forms.DateField and update the widget.
# form_fields.py
from django.forms import DateField
from myapp.widgets import MyWidget
class MyDateFormField(DateField):
widget = MyWidget
And then after you have your form field created, you're going to have to override the django model field to default to your new form field
# fields.py
from django.db.models import DateField
from myapp.form_fields import MyDateFormField
class MyDateField(MyDateFormField):
def formfield(self, **kwargs):
defaults = {'form_class': MyDateFormField}
defaults.update(kwargs)
return super(DateField, self).formfield(**defaults)
You would then have your custom model field, which you would need to slightly change your code to use.
from myapp.fields import MyDateField
class MyModel(models.Model):
date=MyDateField()
It's not exactly what you were asking for (have to change the model field), but hopefully this gets you in the right direction.
Create your field
Create form that will use this field by default
import this form instead of default form, when you use it
If you're using it in admin:
create your own ModelAdmin that will use your form by default
use that instead of default ModelAdmin.

Admin Form Integration for Custom Model Fields in Django

I need a model field composed of a numeric string for a Django app I'm working on and since one doesn't exist I need to roll my own. Now I understand how "get_db_prep_value" and such work, and how to extend the Model itself (the django documentation on custom model fields is an invaluable resource.), but for the life of me I can't seem to figure out how to make the admin interface error properly based on input constraints.
How do I make the associated form field in the admin error on incorrect input?
Have a look at the Form and field validation section in the Django documentation, maybe that's what you're looking for?
You would have to make a new type of form field for your custom model field.
All you need to do is define a custom modelform which uses your new field, and then tell the admin to use that form to edit your models.
class MyModelForm(forms.ModelForm):
myfield = MyCustomField()
class Meta:
model = MyModel
class MyModelAdmin(admin.ModelAdmin):
form = MyModelForm