嵌套的URL不能与Django REST框架一起使用

时间:2014-11-04 11:34:29

标签: django django-rest-framework django-urls

url.py
router.register(r'Costumers', CostumerViewSet, base_name='costumer')
  .register(r'Agreements', AgreementViewSet, base_name='agreement', parents_query_lookups=['costumer']).
      .register(r'Programs', ProgramViewSet,base_name='programs',parents_query_lookups=['agreement']),

model.py

class Costumer(models.Model):
  company_name = models.CharField(max_length=300)
  supplier = models.ForeignKey(Supplier)

class Agreement(models.Model): 
  agreement_name = models.CharField(max_length=300)
  programs = models.ManyToManyField(Program, through='Programs_in_Agreement')
  costumer = models.ForeignKey(Costumer)

class Program(models.Model):
  program_name = models.CharField(max_length=300)

class Programs_in_Agreement(models.Model):
   programs = models.ForeignKey(Program)
   agreement = models.ForeignKey(Agreement)

Im trying to get this page 
/api/v1/Costumers/1/Agreements/1/Programs/

and I've got this error
"^Costumers/(?P<parent_lookup_agreement>[^/.]+)/Agreements/(?P<parent_lookup_agreement>[^/.]+)/Programs/$" is not a valid regular expression: redefinition of group name 'parent_lookup_agreement' as group 2; was group 1

计划与协议之间的关系是M2M 协议和客户之间的关系是M21 能帮我吗?

1 个答案:

答案 0 :(得分:3)

您正在嵌套路由器,这意味着您正在使用其中一个嵌套路由器插件。问题是您没有提供上次register电话的所有查询字段。

你想要达到的关系是

  

计划 - &gt;协议 - &gt;的costumers

路由器正在生成

  

的costumers
  协议 - &gt;的costumers
  计划 - &gt;协议 - &gt;的costumers

->表示正在进行查找的信号。 通过传递parents_query_lookups进行注册时,必须手动提供。这很重要,否则插件必须猜测查找是什么,并且它一定是错误的。在路由器的嵌套之间不会查找查找,因此路由器A上定义的查找不会传递给路由器B,路由器B上的也必须重复

那么在注册路由器时你应该做的就是传递父查找。下面的代码段应该有效:

router.register(r'Costumers', CostumerViewSet, base_name='costumer')
  .register(r'Agreements', AgreementViewSet, base_name='agreement', parents_query_lookups=['costumer']).
      .register(r'Programs', ProgramViewSet, base_name='programs', parents_query_lookups=['agreement__costumer', 'agreement'])

请注意,在agreement__costumer中为最后一次通话添加了parents_query_lookups。这允许插件填写URL部分的查找字段,防止重复的组显示。