简体   繁体   English

如何在 Django 中正确使用 UUID id 作为 url 参数?

[英]How do I properly use a UUID id as a url parameter in Django?

I've been trying to pass a UUID4 id into the url for a specific detail page.我一直在尝试将 UUID4 id 传递给 url 以获得特定的详细信息页面。

After browsing Stackoverflow and other sites, here's what I've tried so far:浏览 Stackoverflow 和其他网站后,这是我迄今为止尝试过的:

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

But this raises the error: Generic detail view CarDetailView must be called with either an object pk or a slug in the URLconf.但这会引发错误:必须使用 object pk 或 URLconf 中的 slug 调用通用详细视图 CarDetailView。 . .

Since the uuid field is composed of both letters and numbers, I can't use an int.由于 uuid 字段由字母和数字组成,我不能使用 int。

  1. So I used this:所以我用了这个:

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

which returns the messy and broken url: showroom/%5E(%3FP09c32f72-5863-49fa-a42a-1d0fed274c4e%5Cw+)/$它返回凌乱而破碎的 url: showroom/%5E(%3FP09c32f72-5863-49fa-a42a-1d0fed274c4e%5Cw+)/$

  1. Then I tried reverting to the original, but using a def_object method in the View class.然后我尝试恢复到原始,但在视图 class 中使用def_object方法。
def get_object(self):
    object = get_object_or_404(CarInstance,title=self.kwargs['car_model'])
    return object

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

models.py模型.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视图.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)])

The urls should be be formatted as showroom/car/09c32f72-5863-49fa-a42a-1d0fed274c4e/ , which brings up the detail view for the specific object. url 的格式应为showroom/car/09c32f72-5863-49fa-a42a-1d0fed274c4e/ ,这将显示特定 object 的详细视图。

Any ideas?有任何想法吗?

Update更新

According to the answer below, I changed the get_object override to根据下面的答案,我将 get_object 覆盖更改为

    slug_field = 'title'
    slug_url_kwarg = 'car_detail'

But I'm still getting the same urlconf must be called with slug or int error.但我仍然得到相同的 urlconf 必须用 slug 或 int 错误调用。 Should I define the slugh in the models?我应该在模型中定义泥浆吗?

Update 2更新 2

I've changed the urlconf, but it's raising the same error.我已经更改了 urlconf,但它引发了同样的错误。 Here's the full traceback这是完整的追溯

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.

** Another update ** **另一个更新**

Thanks to help from @ruddra, I changed the path to match the slug_url_kwarg = 'car_detail' It looks like this now:感谢@ruddra 的帮助,我更改了路径以匹配 slug_url_kwarg = 'car_detail' 现在看起来像这样:

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

However, now the page raises a 404 error.但是,现在该页面引发了 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

You don't need to override get_object() method.您不需要覆盖get_object()方法。 You can simply use slug_url_kwarg and slug_field .您可以简单地使用slug_url_kwargslug_field Like this:像这样:

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

More information can be found in get_object() documentation.更多信息可以在get_object()文档中找到。

1.create get_absolute_url() in models.py: 1.在models.py中创建get_absolute_url():

def get_absolute_url(self):
    return reverse('car-detail', args=[str(self.<yourUUIDFieldName>)]) # self.car_model

2.set url in urls.py: 2.在urls.py中设置url:

urlpatterns = [
    path('car/<uuid:yourUUIDFieldName>/', # 'car:<uuid:car_model'>
     views.CarDetailView.as_view(), name='car-detail'),
]

3.try to change views as: 3.尝试将视图更改为:

class CarDetailView(DetailView):
     model = CarInstance
     slug_field = '<uuid:yourUUIDFieldName>' # -> 'car_model'
     slug_url_kwarg = '<uuid:yourUUIDFieldName>' # -> 'car_model'
     template_name = 'car_detail.html' 

4.in addition try this if you like: 4.如果你喜欢,另外试试这个:

import uuid
car_model = models.UUIDField(default=uuid.uuid4, unique=True)

replace yourUUIDFieldName with car_model check if this work, in my way, i have no idea, i'm just a beginner like others, hope u get something out of itcar_model替换yourUUIDFieldName检查这是否可行,以我的方式,我不知道,我和其他人一样只是初学者,希望你能从中有所收获

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM