好吧,我有两个用于存储问题和问卷的django模型。每个问题都在问卷中。每个问题都应该有一个字段来存储它将出现在问卷中的顺序。我的问题是按问题顺序处理变更的最佳方法是什么。
代码适用于模型:
class Questionnaire(models.Model):
name = models.CharField(max_length = 100)
time_creation = models.DateTimeField(auto_now=True)
class Question(models.Model):
questionnaire = models.ForeignKey(Questionnaire, related_name='questions', on_delete=models.CASCADE)
text = models.TextField()
order = models.IntegerField()
我想到的一种方法是重写Question模型的save方法,就像这样:
def save(self, *args, **kwargs):
all_questions = self.questionnaire.questions.all()
if (self.order == None or self.order > len(all_questions)+1 or self.order == 0):
self.order = len(all_questions)+1 # starts in 1
else:
previous = all_questions.filter(order=self.order)
if len(previous)>0:
p = previous[0]
p.order = self.order+1
p.save()
super().save(*args, **kwargs)
这是一种递归函数,在save()内部,我验证是否存在一个具有相同订单号的Question并将其增加,然后调用save(在save内部),对此对象将执行相同的操作。 / p>
这是解决问题的好方法吗? Django有一些我可能不了解的特性,后来可能会咬我。我应该使用信号吗?是否发布保存?谢谢您的帮助!
答案 0 :(得分:1)
Django通过模型元选项order_with_respect_to提供了一种非常简单的机制。 我相信使用它已经可以使事情变得简单:
class Question(models.Model):
questionnaire = models.ForeignKey(Questionnaire)
# ...
class Meta:
order_with_respect_to = 'questionnaire'
这为Questionnaire
模型添加了两种方法。两者都允许您使用Question
主键列表处理Question
对象的顺序。
questionnaire = Questionnaire.objects.get(id=1)
questionnaire.get_question_order()
[1, 2, 3]
questionnaire.set_question_order([3, 1, 2])
请注意,此操作将向数据库添加一个_order
列,并隐式设置ordering
来使用它。
您现在可以通过处理订单列表来实现所有其他业务逻辑。只是用于查找Question
对象顺序的示例帮助程序:
questionnaire = Questionnaire.objects.get(id=1)
question_order = questionnaire.get_question_order()
question = Question.objects.get(foo='bar')
position = question_order.index(question.pk)
我不确定您是否真的应该走这条路(使用order
字段),但是如果这样做,至少要使用PositiveIntegerField
并将其约束为唯一。我不知道您的输入来自何处,但是您应该始终尝试将它们清理成一个序列,将它们放入列表中,然后立即设置Question
对象的顺序。