1
mengzhuo 2014-08-04 11:18:34 +08:00 1
请检讨一下你的数据库设计
-------------------------------- 另:这个叫default https://docs.djangoproject.com/en/dev/ref/models/fields/#default |
2
magine OP |
4
yueyoum 2014-08-04 12:21:28 +08:00 1
|
5
magine OP |
6
yueyoum 2014-08-04 13:16:53 +08:00
django 文档很优秀了。 右侧有导航。
不过要学习一个新东西,最有效的方式就是 把文档一个字一个字的看一边。 而不是直接按照自己的想法 去搜索 |
7
magine OP @yueyoum
文档里说,The default cannot be a mutable object。 我希望default接受的是一个动态的函数结果,类似于这样: https://gist.github.com/12ac8b2525f0fb6301fa 是不是就不得不放在view中实现了? |
8
yueyoum 2014-08-04 13:31:38 +08:00 1
@magine gist 半天没打开,挂代理也没用。
我大概知道你什么意思。 如果一个字段要提供 动态变化的默认值 可以在views里做,不过还是不推荐。 如果是和其他业务逻辑没什么关联的,推荐重写Model的 save 方法 class Question(models.Model): num = models.SmallIntegerField() def save(self, *args, **kwargs): self.num = Question.objects.filter(paper=self.paper).count() + 1 super(Question, self).save(*args, **kwargs) 但其实这段代码并不安全, 如果有两个 Question.objects.create() 并发执行了, 那么新存入的 这两个 的num有可能一样。 所以安全做法还是用 signals from django.db.models.signals import post_save class Question(models.Model): num = models.SmallIntegerField() def save_handler(instance, change, **kwargs): if change: return instance.num = Question.objects.filter(paper=instance.paper).count() + 1 instance.save() post_save.connent(save_handler, sender=Question) 上面代码是凭记忆写的, 有些参数可能错误。 |
9
magine OP @yueyoum
第一种方法对我来说暂时是安全的, 因为只有使用教师帐号登陆之后才会拥有创建考卷的权利, 而且新建的考卷中有外键指向这一帐号。 (一般不会出现一个老师帐号多人登陆还修改同一套试卷的坑爹状况吧……) 额……第二种方法我还没看懂!QAQ 每次提问django问题都有你,大神等有机会去成都一定当面道谢啊。 |
10
yueyoum 2014-08-04 16:27:38 +08:00
@magine
不是大神……………… 我觉得你 Question 中的 num (题号) 的生成方式有 隐患 比如 已经生成了 1,2,3,4 个 Question, 他们的num分别是 1,2,3,4 然后把 3号 Question删除了, 再创建一个新的 Question 那么这个新 Question的num 也是4, 这组题目中就有两个 题号为4 的 题目了。 想要题号不重复,应该是这么做: from django.db.models import Max if Question.objects.count() == 0: ....new_num = 1 else: ....num_num = Question.objects.aggregate(Max(num))['num__max'] + 1 这种情况下, 删除3号,再创建新的 Question,其num为 5, 但是 虽然题号没重复,但是 已经不连续了。 所以最好 在 Question 的 Listview admin 上提供一个按钮, 自动重置题号, 会自动将这些 nums 依次递增排列。 |
16
magine OP @yueyoum
``` ItemFormSet = forms.models.inlineformset_factory( Order, Item, ) class AddOrderView(CreateView): template_name = 'new_order.html' form_class = OrderForm def get_context_data(self, **kwargs): context = super(AddOrderView, self).get_context_data(**kwargs) if self.request.POST: context['item_formset'] = ItemFormSet(self.request.POST) else: context['item_formset'] = ItemFormSet() return context def formset_invalid(self, form): return self.render_to_response(self.get_context_data(form=form)) def form_valid(self, form): context = self.get_context_data() formset = context['item_formset'] if formset.is_valid(): self.object = form.save(self.request.user) # set the order_fk for items formset.instance = self.object formset.save() return redirect(reverse('core:list_orders')) else: self.formset_invalid(form) # 在存储Item(项目)的时候,自动设置其位于Order(订单)中的序号。 ``` |
17
magine OP |