S_alj S_alj - 21 days ago 6
Python Question

Django's Inline Admin: a 'pre-filled' field

I'm working on my first Django project, in which I want a user to be able to create custom forms, in the admin, and add fields to it as he or she needs them. For this, I've added a reusable app to my project, found on github at:


https://github.com/stephenmcd/django-forms-builder


I'm having trouble, because I want to make it so 1 specific field is 'default' for every form that's ever created, because it will be necessary in every situation (by the way my, it's irrelevant here, but this field corresponds to a point on the map).

An important section of code from this django-forms-builder app, showing the use of admin.TabularInline:

#admin.py
#...
class FieldAdmin(admin.TabularInline):
model = Field
exclude = ('slug', )


class FormAdmin(admin.ModelAdmin):
formentry_model = FormEntry
fieldentry_model = FieldEntry

inlines = (FieldAdmin,)
#...


So my question is: is there any simple way to add default (already filled fields) for an admin 'TabularInline' in the recent Django versions? If not possible, I would really appreciate a pointer to somewhere I could learn how to go about solving this.

Important: I've searched for similar questions here and even googled the issue. I've found some old questions (all from 2014 or way older) that mention this possibility not being directly provided by Django. The answers involved somewhat complex/confusing suggestions, given that I'm a Django begginer.

Answer

There are a couple of ways to achieve this.

1: Set a default on the field in the model.

Django's dynamic admin forms and inlines are smart enough to detect this and display it automatically as a default choice or entry.

class Book(models.Model):

    rating = models.IntegerField(default=0)

2: Use a custom form in your TabularInline class.

class BookInlineForm(models.ModelForm):

    class Meta:
        model = Book
        fields = ('rating', )

    def __init__(self, *args, **kwargs):
        initial = kwargs.pop('initial', {})
        # add a default rating if one hasn't been passed in
        initial['rating'] = initial.get('rating', 0)
        kwargs['initial'] = initial
        super(BookInlineForm, self).__init__(
            *args, **kwargs
        )


class BookTabularInline(admin.TabularInline):
    model = Book
    form = BookInlineForm


class ShelfAdmin(admin.ModelAdmin):
    inlines = (BookAdmin,)