django-admin-sortable2 icon indicating copy to clipboard operation
django-admin-sortable2 copied to clipboard

Headers not aligned with column in (SortableInlineAdminMixin,admin.TabularInline)

Open Skrattoune opened this issue 5 years ago • 10 comments

Hi, I bumped into something strange: in one of my inline, the headers are not aligned with the column content. The content is like shifted one column to the right versus the corresponding header (see snapshot):

image

It's pretty annoying, so I've tried about everything I thought about not to have this bug, changing the column order, putting new columns … looked for solutions on the internet … no chance

So it looks like a genuine bug worth reporting

Skrattoune avatar Jan 11 '20 14:01 Skrattoune

seems to be an overflow error. Try to reduce the amount of characters in the columns rendering fields with a lot of content. I don't think it's related with django-admin-sortable2.

jrief avatar Jan 11 '20 14:01 jrief

Corresponding Model:

class SeriesElement(models.Model):
    #renamed from SeriesPart
    objects = SeriesElementManager() # Add custom manager
    class Admin:
        manager = SeriesElementManager() # Forces admin to use the custom manager 
    
    puzzle = models.ForeignKey(Puzzle,
        on_delete=models.CASCADE,
        verbose_name='Puzzle',
        help_text='Puzzle which is part of this series')
    series = models.ForeignKey(Series,
        on_delete=models.CASCADE,
        verbose_name='Series',
        help_text='Series from which the Puzzle is part of')
    puzzle_index = models.PositiveIntegerField(verbose_name='Order',
        default=0,
        editable=True, 
        help_text='Position of the puzzle in the series sequence of puzzles')
class Series(models.Model):
    puzzles = models.ManyToManyField(Puzzle, through='SeriesElement', related_name='series')
    …

Corresponding admin:

class SeriesElementInline(SortableInlineAdminMixin,admin.TabularInline):
    model = SeriesElement     
    
    def get_queryset(self, request):

        queryset = super().get_queryset(request)
        return queryset.add_puzzle_details().select_related('series')


    readonly_fields=['index','puzzle','difficulty','nb_sucesses', 'nb_fails','comment']

    show_change_link = False 

    
    extra = 0 # to prevent extra lines to be displayed

    def index(self,obj): #to be able to display the index 
        return obj.puzzle_index

Content of the SeriesElementManager is not really relevant. only produces annotations to generate the fields to be displayed

Skrattoune avatar Jan 11 '20 14:01 Skrattoune

seems to be an overflow error. Try to reduce the amount of characters in the columns rendering fields with a lot of content. I don't think it's related with django-admin-sortable2.

Thanks for the quick answer ! could it be the name of the series_element that it displays on each line at the begining of each inline element ? Do you know how I could get rid of it and not display it at all ?

Skrattoune avatar Jan 11 '20 14:01 Skrattoune

I just changed the display name to a shorter version but does not seem to work: image

What do you suggest I should try to attack based on the snapshot ?

Skrattoune avatar Jan 11 '20 14:01 Skrattoune

You can either add own own private CSS file and fiddle with the widths of your <td> elements. Our you can use a method on your InlineAdmin class and point a list_display entry onto it. In that method truncate the text.

jrief avatar Jan 11 '20 14:01 jrief

Except that Series_Element name, nothing was really big. Maximum is 25 to 32 characters

Skrattoune avatar Jan 11 '20 14:01 Skrattoune

more weird:

readonly_fields=['index','difficulty','nb_sucesses', 'nb_fails','comment']
# exclude=['puzzle',] # prevent field to be displayed in change page

gives something ok: image

readonly_fields=['index','difficulty','nb_sucesses', 'nb_fails','comment']
exclude=['puzzle',] # prevent field to be displayed in change page

gives back the same problem: image

if I change class SeriesElementInline(SortableInlineAdminMixin,admin.TabularInline): to class SeriesElementInline(admin.TabularInline):

image

hiding the order column:

    readonly_fields=['index','difficulty','nb_sucesses', 'nb_fails','comment']
    exclude=['puzzle_index','puzzle',]

image

and it is repeatable with the bigger field in: image

That's why I though it should be an admin-sortable2 bug

Skrattoune avatar Jan 11 '20 15:01 Skrattoune

OK, I tried something else: putting back puzzle as the first field to display in admin-sortable2: image It works ok

putting difficulty, another calculated field first: image I'm disappointed, it works

Putting another 1 character field first: image works as well

putting index back to the begining: image Works as well ?!?

some more tests later: image

analysis of the difference: exclude=['puzzle_index']

Confirmation: if I remove exclude=['puzzle_index'] I go back to the same shifting bug !

So ... we found a solution ! => in fact not true: it prevent the new inlines order to be saved !

I let you decide what you want to do with it for the admin-sortable2 project

Skrattoune avatar Jan 11 '20 15:01 Skrattoune

A little feedback...

I tried to implement again adminsortable2 ... and I still have the same display issue: As soon as I try to display an index column in my inline ... I have the display bug.

And if I apply my "so-called" solution (excluding the original index field) ... the display is ok, but I can not save the new display order.

Now that I'm a bit more experienced, I found the problem origin: when inspecting the page html, I see (cf snapshot) that the problem comes with the display of the td node with class original: image

<td class="original">
          <p>
          
          s__1x5x5_Y-2-4-6- .... 8-12-14-20-22-24
          
          
          
            </p>
          <input type="hidden" name="series_elements-0-id" value="757556" id="id_series_elements-0-id">
          <input type="hidden" name="series_elements-0-series" value="2036" id="id_series_elements-0-series">
          <input type="hidden" name="series_elements-0-puzzle_index" value="1" id="id_series_elements-0-puzzle_index">
        </td>

the p node takes the whole width of the table, while the containing td node takes an amount of space similar to the td nodes coming after (such as the one I'm interested in :

  <td class="field-index">
                  <p>1</p>
              </td> 

Could anyone have a look at it? and suggest me a way to deal with it.

I guess that it would be great to add the possibility natively to django-admin-sortable2 to have a column with the index displayed.

Thanks in advance

Skrattoune avatar May 27 '21 16:05 Skrattoune

After some years of pause, I finally found a solution.

solution is to define specifically fields instead of just letting the fields to display being defined through the model definition + readonly_fields

class SeriesElementInline(SortableInlineAdminMixin,admin.TabularInline):
    model = SeriesElement     
    
    readonly_fields=['index','puzzle','difficulty','nb_sucesses', 'nb_fails','comment']

    fields=['index','puzzle','difficulty','nb_sucesses', 'nb_fails','comment']


    def index(self,obj): #to be able to display the index 
        return obj.puzzle_index

Skrattoune avatar Oct 17 '22 17:10 Skrattoune