django-admin-sortable2
django-admin-sortable2 copied to clipboard
Headers not aligned with column in (SortableInlineAdminMixin,admin.TabularInline)
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):
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
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.
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
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 ?
I just changed the display name to a shorter version but does not seem to work:
What do you suggest I should try to attack based on the snapshot ?
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.
Except that Series_Element name, nothing was really big. Maximum is 25 to 32 characters
more weird:
readonly_fields=['index','difficulty','nb_sucesses', 'nb_fails','comment']
# exclude=['puzzle',] # prevent field to be displayed in change page
gives something ok:
readonly_fields=['index','difficulty','nb_sucesses', 'nb_fails','comment']
exclude=['puzzle',] # prevent field to be displayed in change page
gives back the same problem:
if I change class SeriesElementInline(SortableInlineAdminMixin,admin.TabularInline): to class SeriesElementInline(admin.TabularInline):
hiding the order column:
readonly_fields=['index','difficulty','nb_sucesses', 'nb_fails','comment']
exclude=['puzzle_index','puzzle',]
and it is repeatable with the bigger field in:
That's why I though it should be an admin-sortable2 bug
OK, I tried something else:
putting back puzzle as the first field to display in admin-sortable2:
It works ok
putting difficulty, another calculated field first:
I'm disappointed, it works
Putting another 1 character field first:
works as well
putting index back to the begining:
Works as well ?!?
some more tests later:
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
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
:
<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
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