第二级关系(类似于 Rails 的 has_many :through)



我有以下模型设置(删除了不相关的部分(:

class Client(models.Model):
name = models.CharField(max_length=200, unique=True)
class Vehicle(models.Model):
client = models.ForeignKey(Client, on_delete=models.PROTECT, related_name="vehicles")
vin = models.CharField(max_length=200, unique=True)
class Chip(models.Model):
vehicle = models.ForeignKey(Vehicle, on_delete=models.PROTECT)
serial_number = models.CharField(max_length=200, unique=True)

有没有一种简单的方法(通过Vehicle表(获取属于特定客户的所有芯片?类似于Rails中的has_many :through

喜欢能够称之为

client = Client.objects.first()
chips = client.chips.all()

[EDIT]为上下文添加更多信息

视图:

class ClientDetailView(DetailView):
model = Client
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
section = self.kwargs['section']
context['section'] = section
if section == 'chips':
context['chips'] = Chip.objects.filter(
vehicle__client=self.get_object())
return context
def get_template_names(self):
if self.kwargs['section'] == 'vehicles':
return ('clients/client_vehicle_list.html',)
elif self.kwargs['section'] == 'chips':
return ('clients/client_chip_list.html',)
return ('clients/client_detail.html',)

ulrconf:

path('clients/<int:pk>/', views.ClientDetailView.as_view(),
name='client-detail', kwargs={"section": None}),
path('clients/<int:pk>/vehicles/', views.ClientDetailView.as_view(),
name='client-detail', kwargs={"section": "vehicles"}),
path('clients/<int:pk>/chips/', views.ClientDetailView.as_view(),
name='client-detail', kwargs={"section": "chips"}),

模板被拆分到多个文件中,但这里是最重要的一个:

// client_chip_list.html
{% extends 'base.html' %} {% block content %}
{% include 'section_title.html' with icon='bi-building' title=client %}
{% include 'clients/client_detail_tabs.html' %} // used to switch between sections (templates)
{% include 'chips/chip_table.html' with chips=chips %}
{% endblock %}

我最终把它放在了模型上,以保持视图的精简:

class Client(models.Model):
...
@property
def chips(self):
return Chip.objects.filter(vehicle__client=self)

最新更新