我正在使用django-1.9和select2使我的用户能够选择,创建和排序他们书籍中的章节和图像数据之间的关系。
models.py
class Section(django.Model):
title = models.CharField(max_length=500)
parent = models.ForeignKey('self', related_name='subsections', null=True, blank=True)
phrases = models.ManyToManyField(Image, through=ImageOrdering, blank=True, related_name='sections')
class Image(models.Model):
name = models.CharField()
class ImageOrdering(models.Model):
section = models.ForeignKey('Section', on_delete=models.CASCADE)
image = models.ForeignKey('Image', on_delete=models.CASCADE)
order = models.IntegerField()
class Meta:
ordering = ['order', ]
forms.py
class SortedSelectMultiple(forms.SelectMultiple):
def render(self, name, value, attrs=None, choices=()):
""" The selected values need to be rendered sorted and last. """
choices = list((image.pk, str(image)) for image in Image.objects.filter(id__in=value))
choices.sort(key=lambda image: value.index(int(image[0])))
self.choices.queryset = Images.objects.exclude(id__in=value)
return super(SortedSelectMultiple, self).render(name, value, attrs, choices)
class SectionForm(forms.ModelForm):
class Meta:
model = Section
fields = ('title', 'images')
widgets = {
'title': forms.TextInput(attrs={'class': 'form-control'}),
# 'images': forms.SelectMultiple(attrs={'class': 'form-control select2-multiple-sortable'}),
'images': SortedSelectMultiple(attrs={'class': 'form-control select2-multiple-sortable'}),
}
def save(self, commit=True):
""" All this hackery to preserve the order. """
this = super(SectionForm, self).save(False)
if commit:
this.save()
self.instance.images.clear()
sort_order = dict(self.data).get('images')
images = list(self.cleaned_data['images'])
images.sort(key=lambda image: sort_order.index(str(image.pk)))
for index, image in enumerate(images):
ordering, created = ImageOrdering.objects.get_or_create(image=image, section=self.instance, order=index)
ordering.save()
return self.instance
我发现这是保留用户拖放元素后Select2给其元素的顺序的唯一方法。元素的DOM顺序用于确定顺序。为此,我必须在呈现表单时保留它。
我觉得我在这里做的事非常丑陋,而且至少不是Pythonic,但是整整一整天的头发我找不到理智的解决方案。也许我想要达到的目的(选项的顺序)是错误的方法?