Django 2.0 - 尝试从具有2个pk段的URL显示详细记录

时间:2018-03-26 21:05:29

标签: python django

我无法在网址中获取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']

2 个答案:

答案 0 :(得分:3)

好像你已经弄乱了你的例子中的缩进

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'])

答案 1 :(得分:1)

在详细视图中,您的get_queryset方法应该返回客户端对象的查询集,就像在列表视图中一样。

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

    def get_queryset(self):
       return HardwareClientServers.objects.filter(client=self.kwargs['pk'])

设置pk_url_kwarg = 'spk'告诉Django应该使用self.kwargs['spk']来获取对象。

或者,您可以删除get_querysetpk_url_kwarg,然后覆盖get_object,如АлександрТатаринов的回答所示。