我有两个具有外键关系的模型Book
和Chapters
。>
我正在尝试按INSERT
字段排序的现有章节Chapter
之间的QuerySet
一个order
,但是在以下方面遇到了麻烦:
order
之后依次维护INSERT
。QuerySet
不允许负索引。示例:
说我已经有第1至10章。现在,我需要在1和2之间添加一个new Chapter
。因此,new Chapter应该在数据库。因此2之后的所有章节及其本身都应具有order
的order + 1
,以便为新章节腾出空间。我的代码:
models.py
class Book(PubDateUpdDateMixin, models.Model):
title = models.CharField(max_length=80)
slug = models.SlugField(unique=True, blank=True)
description = models.CharField(max_length=3000)
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='authors')
class chapter(PubDateUpdDateMixin, models.Model):
book = models.ForeignKey(Book, on_delete=models.CASCADE, related_name='chapters')
title = models.CharField(max_length=40)
content = models.TextField(max_length=30000)
slug = models.SlugField(unique=True, blank=True)
order = models.IntegerField(null=True)
views.py
class ChapterCreate(LoginRequiredMixin, CreateView):
login_url = reverse_lazy('login')
model = Chapter
slug_url_kwarg = 'book_slug'
form_class = ChapterForm
template_name_suffix = '-create'
def get_object(self):
return Book.objects.get(slug=self.kwargs['book_slug'])
def get_context_data(self, **kwargs):
context = super(ChapterCreate, self).get_context_data(**kwargs)
context['book'] = Book.objects.get(slug=self.kwargs['book_slug'])
return context
def form_valid(self, form):
book = self.get_object()
chapter = form.save(commit=False)
chapter.book = book
requested_order = form.cleaned_data['order']
if requested_order == chapter.order:
'''
Reverse the queryset and slice it up to the requested order.
Add 1 to the chapter orders (chapter.order + 1).
Save them to create a slot for the new chapter.
'''
chapters = course.chapters.order_by("-order")
for l in chapters[:((len(chapters)+1)-requested_order)]:
l.order += 1
print(l.order)
l.save()
try:
chapter.save()
except IntegrityError as e:
raise IntegrityError("Error: {}".format(e))
return super(ChapterCreate, self).form_valid(form)
def dispatch(self, *args, **kwargs):
book = self.get_object()
if not self.request.user.is_authenticated:
messages.info(self.request, 'You need to be logged in to edit a chapter.')
elif book.author != self.request.user:
raise PermissionDenied
return super(ChapterCreate, self).dispatch(*args, **kwargs)
这适用于顺序排序,但不适用于当切片索引变为负数时。
我有两个具有外键关系的模型Book和Chapters。我正在尝试在按订单字段排序的现有章节QuerySet之间插入一章,但在...
# Increment all chapter orders greater or equal to the requested order:
book.chapters.filter(order__gte=requested_order).update(order=F("order") + 1)
# Now just set the order directly on the object:
chapter.order = requested_order
chapter.save()
Documentation for F expressions。
看来这对您不起作用,您可能必须逐一更新各章:
for chapter_to_update in book.chapters.filter(
order__gte=requested_order
).order_by('-order'):
chapter_to_update.order += 1
chapter_to_update.save()
chapter.order = requested_order
chapter.save()
如果您在书中有很多章节,这会比较慢。