S_alj
S_alj

Reputation: 447

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.

Upvotes: 3

Views: 3082

Answers (2)

Amrit Prasad
Amrit Prasad

Reputation: 427

This is a simple possbile way to add default(per-filled) data in Django admin panel for InlineModelAdmin

class FieldAdmin(admin.TabularInline):
    model = Field
    fields = ('type', 'amount')

    def get_formset(self, request, obj=None, **kwargs):
        formset = super().get_formset(request, obj, **kwargs)
        formset.form.base_fields['amount'].initial = 20
        return formset

Upvotes: 0

lukewarm
lukewarm

Reputation: 857

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,)

Upvotes: 3

Related Questions