异常值:必须使用对象 pk 或 slug 调用通用详细信息视图 TransactionDetailView
Exception Value: Generic detail view TransactionDetailView must be called with either an object pk or a slug
当我试图从我的交易列表页面访问交易详情页面时出现此错误。我使用 UUID (primary=true) 作为交易详情页面的 PK。
memberships/models.py
class Transaction(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="user_transaction")
order_id = models.CharField(max_length=36, blank=True, unique=True, default=uuid.uuid4, primary_key=True, editable=False)
membership = models.ForeignKey(Membership, on_delete=models.SET_NULL, null=True, blank=True)
amount = models.DecimalField(max_digits=100, decimal_places=2)
success = models.BooleanField(default=True)
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
def __str__(self):
return self.order_id
class Meta:
ordering = ['-timestamp']
urls.py
...removed imports
urlpatterns = [
#Generic
url(r'^django-admin/', admin.site.urls),
url(r'^admin/', include(wagtailadmin_urls)),
url(r'^documents/', include(wagtaildocs_urls)),
url(r'^search/$', search_views.search, name='search'),
#Authentication
url(r'^accounts/', include('allauth.urls')),
#Product
url(r'^portal/', include(('portal.urls', 'portal'), namespace='portal')),
#Payment
url(r'^checkout/', include(('checkout.urls', 'checkout'), namespace='checkout')),
#Membership
url(r'^membership/', include(('memberships.urls', 'memberships'), namespace='memberships')),
#Rating
url(r'^ratings/', include('star_ratings.urls', namespace='ratings')),
#Users
url(r'^users/$', UserListView.as_view(), name='users_list'),
url(r'^profile/$', userPage, name='userPage'),
url(r'^users/~redirect/$', UserRedirectView.as_view(), name='redirect'),
url(r'^users/(?P<username>[\w.@+-]+)/$', UserDetailView.as_view(), name='detail'),
url(r'^users/(?P<username>[\w.@+-]+)/summary/$', SummaryDetailView.as_view(), name='summary'),
url(r'^users/~update/$', UserUpdateView.as_view(), name='update'),
url(r'^users/redirectprofile/$', RedirectProfileView.as_view(), name='redirectprofile'),
# For anything not caught by a more specific rule above, hand over to
# Wagtail's page serving mechanism. This should be the last pattern in
# the list:
url(r'', include(wagtail_urls)),
# Alternatively, if you want Wagtail pages to be served from a subpath
# of your site, rather than the site root:
# url(r'^pages/', include(wagtail_urls)),
]
if settings.DEBUG:
from django.conf.urls.static import static
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
# Serve static and media files from development server
urlpatterns += staticfiles_urlpatterns()
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
memberships/urls.py
from django.urls import path
from .views import (
MembershipSelectView,
PaymentView,
success,
updateTransactionRecords,
user_subscriptions_view,
cancelSubscription,
TransactionDetailView,
TransactionListView,
SubscriptionDetailView,
SubscriptionListView,
adminPanel,
permission_denied
)
app_name = 'memberships'
urlpatterns = [
path('', MembershipSelectView.as_view(), name='select'),
path('payment/', PaymentView, name='payment'),
path('success/', success, name='purchase_success'),
path('update-transactions/<subscription_id>/', updateTransactionRecords, name='update-transactions'),
path('subscription/', user_subscriptions_view, name='user_subscription'),
path('cancel/', cancelSubscription, name='cancel'),
#TODO MAKE SURE ONLY SUPERUSERS CAN VIEW THESE PAGES
path('transactions/', TransactionListView.as_view(), name='transaction_list'),
path('transaction/<uuid:order_id>/', TransactionDetailView.as_view(), name='transaction_detail'),
path('subscriptions/', SubscriptionListView.as_view(), name='subscription_list'),
path('subscription/<slug:id>/', SubscriptionDetailView.as_view(), name='subscription_detail'),
path('admin/', adminPanel, name='admin_panel'),
path('permission_denied/', permission_denied, name='permission_denied')
]
memberships/views.py
class TransactionDetailView(DetailView):
model = Transaction
slug_field = 'order_id'
memberships/transaction_list.html
{% if object_list %}
{% for transaction in object_list %}
<tr class="text-left">
<td ><strong><a href="{% url 'memberships:transaction_detail' transaction.order_id %}" class="text-dark">{{ transaction.user }}</a></strong></td>
<td class="text-dark">{{ transaction.order_id }}</td>
<td class="text-dark ">{{ transaction.timestamp }}</td>
<td class="text-dark ">{{ transaction.success }}</td>
<td class="text-dark">$ {{ transaction.amount }}</td>
</tr>
{% endfor %}
{% else %}
<p>There were no transactions found.</p>
{% endif %}
编辑:我添加了我的主要 urls.py 和 memberships/urls.py。交易页面在memberships.urls.
下
您已将视图的 slug_field
参数设置为 order_id
,但您尚未告诉它从何处获取该字段的值;正如错误所说,视图仍然期望 URL 给它 pk
或 slug
。
事实上,您的 order_id
是主键,而不是 slug,无论您的主键是什么,Django 都已经有了一个别名:pk
。所以你应该用 pk_url_kwarg
.
替换那个属性
class TransactionDetailView(DetailView):
model = Transaction
pk_url_kwarg = 'order_id'
您需要更新视图中的 slug_url_kwarg
。例如:
class TransactionDetailView(DetailView):
model = Transaction
slug_field = 'order_id'
slug_url_kwarg = 'order_id'
...
因为基于 this code,slug 值是通过视图的属性 slug_url_kwarg
从 kwargs 中获取的。
另外请更新 url 路径。
Url:
path('transaction/<uuid:order_id>/', TransactionDetailView.as_view(), name='transaction_detail'),
当我试图从我的交易列表页面访问交易详情页面时出现此错误。我使用 UUID (primary=true) 作为交易详情页面的 PK。
memberships/models.py
class Transaction(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="user_transaction")
order_id = models.CharField(max_length=36, blank=True, unique=True, default=uuid.uuid4, primary_key=True, editable=False)
membership = models.ForeignKey(Membership, on_delete=models.SET_NULL, null=True, blank=True)
amount = models.DecimalField(max_digits=100, decimal_places=2)
success = models.BooleanField(default=True)
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
def __str__(self):
return self.order_id
class Meta:
ordering = ['-timestamp']
urls.py
...removed imports
urlpatterns = [
#Generic
url(r'^django-admin/', admin.site.urls),
url(r'^admin/', include(wagtailadmin_urls)),
url(r'^documents/', include(wagtaildocs_urls)),
url(r'^search/$', search_views.search, name='search'),
#Authentication
url(r'^accounts/', include('allauth.urls')),
#Product
url(r'^portal/', include(('portal.urls', 'portal'), namespace='portal')),
#Payment
url(r'^checkout/', include(('checkout.urls', 'checkout'), namespace='checkout')),
#Membership
url(r'^membership/', include(('memberships.urls', 'memberships'), namespace='memberships')),
#Rating
url(r'^ratings/', include('star_ratings.urls', namespace='ratings')),
#Users
url(r'^users/$', UserListView.as_view(), name='users_list'),
url(r'^profile/$', userPage, name='userPage'),
url(r'^users/~redirect/$', UserRedirectView.as_view(), name='redirect'),
url(r'^users/(?P<username>[\w.@+-]+)/$', UserDetailView.as_view(), name='detail'),
url(r'^users/(?P<username>[\w.@+-]+)/summary/$', SummaryDetailView.as_view(), name='summary'),
url(r'^users/~update/$', UserUpdateView.as_view(), name='update'),
url(r'^users/redirectprofile/$', RedirectProfileView.as_view(), name='redirectprofile'),
# For anything not caught by a more specific rule above, hand over to
# Wagtail's page serving mechanism. This should be the last pattern in
# the list:
url(r'', include(wagtail_urls)),
# Alternatively, if you want Wagtail pages to be served from a subpath
# of your site, rather than the site root:
# url(r'^pages/', include(wagtail_urls)),
]
if settings.DEBUG:
from django.conf.urls.static import static
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
# Serve static and media files from development server
urlpatterns += staticfiles_urlpatterns()
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
memberships/urls.py
from django.urls import path
from .views import (
MembershipSelectView,
PaymentView,
success,
updateTransactionRecords,
user_subscriptions_view,
cancelSubscription,
TransactionDetailView,
TransactionListView,
SubscriptionDetailView,
SubscriptionListView,
adminPanel,
permission_denied
)
app_name = 'memberships'
urlpatterns = [
path('', MembershipSelectView.as_view(), name='select'),
path('payment/', PaymentView, name='payment'),
path('success/', success, name='purchase_success'),
path('update-transactions/<subscription_id>/', updateTransactionRecords, name='update-transactions'),
path('subscription/', user_subscriptions_view, name='user_subscription'),
path('cancel/', cancelSubscription, name='cancel'),
#TODO MAKE SURE ONLY SUPERUSERS CAN VIEW THESE PAGES
path('transactions/', TransactionListView.as_view(), name='transaction_list'),
path('transaction/<uuid:order_id>/', TransactionDetailView.as_view(), name='transaction_detail'),
path('subscriptions/', SubscriptionListView.as_view(), name='subscription_list'),
path('subscription/<slug:id>/', SubscriptionDetailView.as_view(), name='subscription_detail'),
path('admin/', adminPanel, name='admin_panel'),
path('permission_denied/', permission_denied, name='permission_denied')
]
memberships/views.py
class TransactionDetailView(DetailView):
model = Transaction
slug_field = 'order_id'
memberships/transaction_list.html
{% if object_list %}
{% for transaction in object_list %}
<tr class="text-left">
<td ><strong><a href="{% url 'memberships:transaction_detail' transaction.order_id %}" class="text-dark">{{ transaction.user }}</a></strong></td>
<td class="text-dark">{{ transaction.order_id }}</td>
<td class="text-dark ">{{ transaction.timestamp }}</td>
<td class="text-dark ">{{ transaction.success }}</td>
<td class="text-dark">$ {{ transaction.amount }}</td>
</tr>
{% endfor %}
{% else %}
<p>There were no transactions found.</p>
{% endif %}
编辑:我添加了我的主要 urls.py 和 memberships/urls.py。交易页面在memberships.urls.
下您已将视图的 slug_field
参数设置为 order_id
,但您尚未告诉它从何处获取该字段的值;正如错误所说,视图仍然期望 URL 给它 pk
或 slug
。
事实上,您的 order_id
是主键,而不是 slug,无论您的主键是什么,Django 都已经有了一个别名:pk
。所以你应该用 pk_url_kwarg
.
class TransactionDetailView(DetailView):
model = Transaction
pk_url_kwarg = 'order_id'
您需要更新视图中的 slug_url_kwarg
。例如:
class TransactionDetailView(DetailView):
model = Transaction
slug_field = 'order_id'
slug_url_kwarg = 'order_id'
...
因为基于 this code,slug 值是通过视图的属性 slug_url_kwarg
从 kwargs 中获取的。
另外请更新 url 路径。
Url:
path('transaction/<uuid:order_id>/', TransactionDetailView.as_view(), name='transaction_detail'),