Python 将具有相同ID的多个数据库对象一起使用unique\u

Python 将具有相同ID的多个数据库对象一起使用unique\u,python,sql,django,django-models,django-rest-framework,Python,Sql,Django,Django Models,Django Rest Framework,假设我有以下结构: class Foo(models.Model): pass class Bar(models.Model): foo = models.ForeignKey(Foo, related_name='bars') 我希望在自动递增ID和父Foo对象上键入单个Bar对象。对于每个Foo我希望下面的条始终是id1,2,3。最终目的是通过URI访问条形码,例如: /foos/1/bars/1 /foos/2/bars/1 请注意,有两个Bar具有相同的ID,但主键

假设我有以下结构:

class Foo(models.Model):
    pass

class Bar(models.Model):
    foo = models.ForeignKey(Foo, related_name='bars')
我希望在自动递增ID和父
Foo
对象上键入单个
Bar
对象。对于每个
Foo
我希望下面的
条始终是id
1,2,3
。最终目的是通过URI访问
条形码,例如:

/foos/1/bars/1
/foos/2/bars/1
请注意,有两个
Bar
具有相同的ID,但主键来自
Bar
及其父
Foo
的ID的唯一性

我想我已经在
Meta
类的
unique\u属性中找到了答案:

class Bar(models.Model):
    foo = models.ForeignKey(Foo, related_name='bars')

    class Meta:
        unique_together = ('foo', 'id')

但不幸的是,这仍然会导致每个
都有一个唯一的ID。我总是希望每个
Foo
的第一个
的ID为1。

不能使用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)

您不能使用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)

作为旁注,我实际上不需要在任何对象上存储这个标识符。而不是

/foos/1/bars/1
在pk设置为1的情况下查找
,我只需接受请求并返回如下内容

Foo.objects.get(id=1).bars.all()[0]
即,由此映射到第一个条。所以

/foos/n/bars/m
使用主键
n
映射到
Foo
下的
m
th
Bar


Daniel的解决方案实际上回答了我原来的问题,所以我接受这个答案。

作为旁注,我实际上不需要在任何对象上存储这个标识符。而不是

/foos/1/bars/1
在pk设置为1的情况下查找
,我只需接受请求并返回如下内容

Foo.objects.get(id=1).bars.all()[0]
即,由此映射到第一个条。所以

/foos/n/bars/m
使用主键
n
映射到
Foo
下的
m
th
Bar


丹尼尔的解决方案实际上回答了我原来的问题,所以我接受这个答案。

谢谢。我想我假设id和pk字段有问题——pk将是每个表的底层唯一值,而id没有这样的约束。您的解决方案是有道理的,但是是的,在这样做时一定要小心。我很惊讶没有一个内置的方法来实现这一点,更重要的是,如果其他人还没有为它实现库的话。再次干杯!谢谢我想我假设id和pk字段有问题——pk将是每个表的底层唯一值,而id没有这样的约束。您的解决方案是有道理的,但是是的,在这样做时一定要小心。我很惊讶没有一个内置的方法来实现这一点,更重要的是,如果其他人还没有为它实现库的话。再次干杯!