6

From the grappelli customization document, it suggested that:

    The sortable-field will not automatically be hidden
 (use a Hidden Input Widget if needed).

However, i have searched for so long and have no idea on what is a "Hidden Input Widget" and how i could be implemented to a Django model. Here is my code:

     # models.py
class video(models.Model):
    category = models.ForeignKey(subCategory)
    index = PositionField('index')
    video_title = models.CharField(max_length=255, blank=True, null=True)
    video_desc = models.TextField(blank=True, null=True)
    main_img = S3EnabledImageField(upload_to='video_img', blank=True, null=True)
    small_img = S3EnabledImageField(upload_to='video_img', blank=True, null=True)
    mid_img = S3EnabledImageField(upload_to='video_img', blank=True, null=True)
    large_img = S3EnabledImageField(upload_to='video_img', blank=True, null=True)
    last_updated = models.DateField(auto_now=True)
    date_added = models.DateField()
    date_modified = models.DateField()
    date_published = models.DateField(blank=True, null=True)
    date_closed = models.DateField(blank=True, null=True)
    status = models.CharField(max_length=7,choices=STATUS_CHOICE)

    class Meta:
        ordering = ('index',)
        verbose_name = 'Video'
        verbose_name_plural = 'Video'

    def __unicode__(self):
        return self.video_title

class video_file(models.Model):
    video = models.ForeignKey(video)
    index = models.PositiveIntegerField()
    file_title = models.CharField(max_length=255, blank=True, null=True)
    #main_file = models.ImageField(upload_to='phoneso/video_file', blank=True, null=True)
    main_file = S3EnabledFileField(upload_to='video_file')
    resolution = models.CharField(max_length=50, blank=True, null=True)
    file_format = models.CharField(max_length=50, blank=True, null=True)
    date_added = models.DateField(auto_now_add=True)
    date_published = models.DateField(auto_now_add=True)
    status = models.CharField(max_length=7,choices=STATUS_CHOICE)

    class Meta:
        ordering = ('index',)
        verbose_name = 'Video File'
        verbose_name_plural = 'Video File'

    def __unicode__(self):
        return self.video.video_title

# admin.py

class video_fileInline(admin.TabularInline):
    fields = ('main_file' , 'resolution' , 'file_format' , 'status', 'index',)
    sortable_field_name = 'index'
    model = video_file
    extra = 1

class videoAdmin(admin.ModelAdmin):
    list_display = ('index' ,  'video_title', 'category' , 'date_added' , 'date_published' , 'status')
    search_fields = ['video_title', 'desc']
    readonly_fields = ('date_added','date_modified')
    list_filter = ['category']
    inlines = [video_fileInline]

class video_fileAdmin(admin.ModelAdmin):
    list_display = ('index' ,  '__unicode__' , 'file_title', 'resolution' , 'file_format' , 'main_file' , 'date_added' , 'date_published' , 'status')
    search_fields = ['video_title', 'desc']

Where should i implemented the suggested "Hidden Input Widget"?

Thank you.

Juho Vepsäläinen
  • 26,573
  • 12
  • 79
  • 105
Bill Kary
  • 685
  • 2
  • 12
  • 27

2 Answers2

9

You can write a form for your model and use it in video_fileInline:

forms.py

class VideoFileForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(VideoFileForm, self).__init__(*args, **kwargs)
        # key should be your sortable-field - in your exaple it's *index*
        self.fields['index'].widget = forms.HiddenInput()

    class Meta:
        model = video_file

admin.py

class video_fileInline(admin.TabularInline):
    fields = ('main_file' , 'resolution' , 'file_format' , 'status', 'index',)
    form = VideoFileForm
    sortable_field_name = 'index'
    model = video_file
    extra = 1
zaan
  • 887
  • 4
  • 12
  • great idea, i am not familiar in python/django and i never know we can override the form object in default admin page. Good inspiration! This solution works fine but the form label "index" is still there, is there any ways to get rid of it? thanks. – Bill Kary Aug 06 '11 at 01:26
  • on the other hand, what is the meaning of "super(VideoFileForm, self).__init__(*args, **kwargs)" ? – Bill Kary Aug 06 '11 at 01:32
  • To get rid of label _index_ put line: `self.fields['index'].label = ''` at the end of _init_ method or put `verbose_name=''` in your model for _index_ field. _super()_ is used for calling parent class constructor. – zaan Aug 06 '11 at 10:08
  • thanks, verbose_name='' works, although the table cell is still there :D – Bill Kary Aug 06 '11 at 10:56
  • 2
    To get rid of that, you can use CSS. For example, if you call the field `position` and use `TabularInline`, this will work: `.grp-th.position { display: none !important }`. – Anatoly Scherbakov Nov 30 '13 at 11:00
2

Now we have

GrappelliSortableHiddenMixin

Which you can use according to the documentation: http://django-grappelli.readthedocs.org/en/latest/customization.html#inline-sortables

Camilo Nova
  • 1,889
  • 1
  • 12
  • 7
  • 1
    Note that you need to put the base classes in order (first `GrappelliSortableHiddenMixin`, and then `admin.TabularInline`) while declaring your inline class. – MrObjectOriented Nov 28 '20 at 19:41