假设我有以下结构:
class Foo(models.Model):
pass
class Bar(models.Model):
foo = models.ForeignKey(Foo, related_name='bars')
我希望单个Bar
对象同时键入自动递增ID 和父Foo
个对象。对于每个Foo
,我希望下面的Bar
始终为id 1,2,3
。最终目标是通过URI访问Bar
,例如:
/foos/1/bars/1
/foos/2/bars/1
请注意,两个 Bar
具有相同的ID,但主键来自Bar
及其父{{id}的唯一性1}}。
我以为我在Foo
课程的unique_together
属性中找到了答案:
Meta
但遗憾的是,这仍然会为每个class Bar(models.Model):
foo = models.ForeignKey(Foo, related_name='bars')
class Meta:
unique_together = ('foo', 'id')
生成一个唯一的ID。我总是希望每个Bar
的第一个Bar
ID为1。
答案 0 :(得分:2)
您无法使用ID执行此操作,因为数据库分配的ID在整个表中始终是唯一的。如果你真的想要这个,你必须定义一个单独的字段,并在每次为你的foo创建一个栏时增加它。
一个天真的实现可能是这样的:
class Bar(models.Model):
foo_order = models.IntegerField()
foo = models.ForeignKey(Foo, related_name='bars')
class Meta:
unique_together = ('foo', 'foo_order')
def save(self, *args, **kwargs):
if not self.foo_order:
self.foo_order = self.bar_set.count() + 1
super(Bar, self).save(*args, **kwargs)
(请注意,这可能会受到各种竞争条件的影响,所以要小心。)
现在,您可以在视图中使用字段组合来获取相关的条形码:
def bar_view(request, foo_id, order):
my_bar = Bar.objects.get(foo_id=foo_id, foo_order=order)
答案 1 :(得分:0)
作为旁注,我实际上并不需要将此标识符存储在任何对象上。而不是
/foos/1/bars/1
导致查找Bar
并将pk设置为1,我可以接受请求并返回类似
Foo.objects.get(id=1).bars.all()[0]
即。从而映射到第一个Bar。所以
/foos/n/bars/m
使用主键m
映射到Bar
下的Foo
n
。