我无法在我的URL中获取2个pk段来过滤视图。第一个pk段是客户端的ID,第二个pk段是服务器记录的id。我尝试不使用默认pk而是使用spk作为服务器ID,但无论尝试如何,我都会不断收到错误消息。任何帮助是极大的赞赏。

模型

class HardwareClientServers(models.Model):
    server_type = models.ForeignKey(HardwareServerTypes, null=True, on_delete=models.PROTECT, blank=True)
    client = models.ForeignKey(Clients , on_delete=models.CASCADE)
    os = models.ForeignKey(HardwareOperatingSystems, null=True, on_delete=models.PROTECT, blank=True)
    virtual = models.BooleanField(default=False)
    memory = models.CharField(max_length=25, null=True, blank=True)
    server_name = models.CharField(max_length=75, null=True, blank=True)


网址

urlpatterns = [
    path('', views.client_list, name='client_list'),
    path('<int:pk>/', views.ClientsDetailView.as_view(), name='client_detail'),
    path('<int:pk>/serverlist/', views.ServerListView.as_view(), name='server_list'),
    path('<int:pk>/serverlist/<int:spk>/', views.ServerDetailView.as_view(), name='server_detail'),]


视图

class ServerListView(ListView):
    model = models.HardwareClientServers
    context_object_name = 'client_servers'
    template_name = 'server_list.html'
    ordering = ['server_name']
    def get_queryset(self):
       return HardwareClientServers.objects.filter(client=self.kwargs['pk'])

class ServerDetailView(DetailView):
    model = models.HardwareClientServers
    context_object_name = 'client_server_details'
    template_name = 'server_details.html'
    def get_queryset(self):
        self.spk = get_object_or_404(HardwareClientServers, id=self.kwargs['spk'])
    return HardwareClientServers.objects.filter(id=self.spk)


我得到的错误

TypeError at /clients/37563347/serverlist/1076/
int() argument must be a string, a bytes-like object or a number, not 'HardwareClientServers'
Request Method: GET
Request URL:    http://127.0.0.1:8000/clients/37563347/serverlist/1076/
Django Version: 2.0.2
Exception Type: TypeError
Exception Value:
int() argument must be a string, a bytes-like object or a number, not 'HardwareClientServers'
Exception Location: C:\Users\rbest\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\models\fields\__init__.py in get_prep_value, line 947
Python Executable:  C:\Users\rbest\AppData\Local\Programs\Python\Python36-32\python.exe
Python Version: 3.6.4
Python Path:
['C:\\Client Support\\Django Projects\\TISRegister',
 'C:\\Users\\rbest\\AppData\\Local\\Programs\\Python\\Python36-32\\python36.zip',
 'C:\\Users\\rbest\\AppData\\Local\\Programs\\Python\\Python36-32\\DLLs',
 'C:\\Users\\rbest\\AppData\\Local\\Programs\\Python\\Python36-32\\lib',
 'C:\\Users\\rbest\\AppData\\Local\\Programs\\Python\\Python36-32',
 'C:\\Users\\rbest\\AppData\\Local\\Programs\\Python\\Python36-32\\lib\\site-packages']

最佳答案

好像您弄乱了示例中的缩进

class ServerDetailView(DetailView):
    model = models.HardwareClientServers
    context_object_name = 'client_server_details'
    template_name = 'server_details.html'
    def get_queryset(self):
        self.spk = get_object_or_404(HardwareClientServers, id=self.kwargs['spk'])
        return HardwareClientServers.objects.filter(id=self.spk)


因此问题出在return HardwareClientServers.objects.filter(id=self.spk)行。

由于self.spk是HardwareClientServers实例,因此不能将其用于过滤器。
相反,使用

return HardwareClientServers.objects.filter(id=self.spk.id)


但是更好的方法是重写get_object,而不是get_queryset方法。
所以代码变成

class ServerDetailView(DetailView):
   model = models.HardwareClientServers
   context_object_name = 'client_server_details'
   template_name = 'server_details.html'

   def get_object(self):
       return get_object_or_404(HardwareClientServers,
                                id=self.kwargs['spk'],
                                client=self.kwargs['pk'])

07-24 09:20