【问题标题】:How do I properly use a UUID id as a url parameter in Django?如何在 Django 中正确使用 UUID id 作为 url 参数?
【发布时间】:2020-01-30 12:25:10
【问题描述】:

我一直在尝试将 UUID4 id 传递到特定详细信息页面的 url。

在浏览了 Stackoverflow 和其他网站之后,这是我目前尝试过的:

  1. 将 url 路径作为path('car/<uuid:id>/', views.CarDetailView.as_view(), name='car-detail'), 传递

但这会引发错误:必须使用 URLconf 中的对象 pk 或 slug 调用通用详细视图 CarDetailView。

由于uuid字段由字母和数字组成,我不能使用int。

  1. 所以我用了这个:

path(r"^(?P<car_model>\w+)/$", views.CarDetailView.as_view(), name='car-detail'),

返回乱七八糟的网址:showroom/%5E(%3FP09c32f72-5863-49fa-a42a-1d0fed274c4e%5Cw+)/$

  1. 然后我尝试恢复到原始状态,但在 View 类中使用 def_object 方法。
def get_object(self):
    object = get_object_or_404(CarInstance,title=self.kwargs['car_model'])
    return object

但这会返回错误:“KeyError at /showroom/car/09c32f72-5863-49fa-a42a-1d0fed274c4e/ 'car_model'"

models.py

class CarInstance(models.Model):
    manufacturer = models.ForeignKey('Manufacturer', on_delete=models.SET_NULL, null=True)
    car_model = models.CharField('Model', max_length=50, null=True)

views.py

class CarDetailView(generic.DetailView):
    model = CarInstance
    template_name = 'car_detail'

    def get_queryset(self):
         return CarInstance.objects.all()

    def get_object(self):
           object = get_object_or_404(CarInstance,title=self.kwargs['car_model'])
           return object

    def get_absolute_url(self):
            return reverse('showroom:car-detail', args=[str(self.pk)])

网址的格式应为 showroom/car/09c32f72-5863-49fa-a42a-1d0fed274c4e/,这会显示特定对象的详细视图。

有什么想法吗?

更新

根据下面的回答,我把get_object覆盖改成了

    slug_field = 'title'
    slug_url_kwarg = 'car_detail'

但我仍然得到相同的 urlconf 必须调用 slug 或 int 错误。我应该在模型中定义 slgh 吗?

更新 2

我已经更改了 urlconf,但它引发了同样的错误。这是完整的回溯

Environment:


Request Method: GET
Request URL: http://localhost:8000/showroom/car/09c32f72-5863-49fa-a42a-1d0fed274c4e/

Django Version: 2.2.5
Python Version: 3.7.4
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'showroom']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback:

File "C:\Users\USER\Envs\torque\lib\site-packages\django\core\handlers\exception.py" in inner
  34.             response = get_response(request)

File "C:\Users\USER\Envs\torque\lib\site-packages\django\core\handlers\base.py" in _get_response
  115.                 response = self.process_exception_by_middleware(e, request)

File "C:\Users\USER\Envs\torque\lib\site-packages\django\core\handlers\base.py" in _get_response
  113.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "C:\Users\USER\Envs\torque\lib\site-packages\django\views\generic\base.py" in view
  71.             return self.dispatch(request, *args, **kwargs)

File "C:\Users\USER\Envs\torque\lib\site-packages\django\views\generic\base.py" in dispatch
  97.         return handler(request, *args, **kwargs)

File "C:\Users\USER\Envs\torque\lib\site-packages\django\views\generic\detail.py" in get
  106.         self.object = self.get_object()

File "C:\Users\USER\Envs\torque\lib\site-packages\django\views\generic\detail.py" in get_object
  47.                 "pk or a slug in the URLconf." % self.__class__.__name__

Exception Type: AttributeError at /showroom/car/09c32f72-5863-49fa-a42a-1d0fed274c4e/
Exception Value: Generic detail view CarDetailView must be called with either an object pk or a slug in the URLconf.

** 另一个更新**

感谢@ruddra 的帮助,我更改了路径以匹配 slug_url_kwarg = 'car_detail' 现在看起来像这样:

path('car/<slug:car_detail>/', views.CarDetailView.as_view(), name='car-detail')

但是,现在页面引发了 404 错误。

Page not found (404)
Request Method: GET
Request URL:    http://localhost:8000/showroom/car/09c32f72-5863-49fa-a42a-1d0fed274c4e/
Raised by:  showroom.views.CarDetailView
No car instance found matching the query

【问题讨论】:

    标签: python django url


    【解决方案1】:

    您不需要重写get_object() 方法。您可以简单地使用slug_url_kwargslug_field。像这样:

    class CarDetailView(generic.DetailView):
        model = CarInstance
        template_name = 'car_detail'
        slug_field = 'title'
        slug_url_kwarg = 'car_model'
    

    更多信息可以在get_object()文档中找到。

    【讨论】:

    • 感谢您的澄清。我仍然收到“必须使用 URLconf 中的对象 pk 或 slug 调用通用详细视图 CarDetailView”。不过。
    • 你可以试试path('car/&lt;uuid:car_model&gt;/', views.CarDetailView.as_view(), name='car-detail')吗?
    • @Rene 来自您的实现,slug_url_kwargcar_detail,因此将 url 更改为 path('car/&lt;uuid:car_detail&gt;/', views.CarDetailView.as_view(), name='car-detail')
    • 表示它没有为您提供的 UUID 找到任何 Car 实例。如果您有具有该 uuid 的实例,请检查数据库或从 django shell 或管理站点。
    • 我将打开一个新问题,因为原始问题已得到解决。
    【解决方案2】:
    1. 在models.py中创建get_absolute_url():
    def get_absolute_url(self):
        return reverse('car-detail', args=[str(self.<yourUUIDFieldName>)]) # self.car_model
    
    1. 在 urls.py 中设置 URL:
    urlpatterns = [
        path('car/<uuid:yourUUIDFieldName>/', # 'car:<uuid:car_model'>
        views.CarDetailView.as_view(), name='car-detail'),
    ]
    
    1. 尝试更改视图:
    class CarDetailView(DetailView):
        model = CarInstance
        slug_field = '<uuid:yourUUIDFieldName>' # -> 'car_model'
        slug_url_kwarg = '<uuid:yourUUIDFieldName>' # -> 'car_model'
        template_name = 'car_detail.html'
    
    1. 如果您愿意,还可以试试这个:
    import uuid
    car_model = models.UUIDField(default=uuid.uuid4, unique=True)
    

    yourUUIDFieldName 替换为car_model 检查是否可行, 以我的方式,我不知道,我和其他人一样只是一个初学者,希望你能从中有所收获

    【讨论】:

      猜你喜欢
      • 2020-11-13
      • 2015-08-21
      • 2018-06-06
      • 2016-12-27
      • 2020-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-29
      相关资源
      最近更新 更多