[英]How to pass pk argument within class based view to queryset in Django
我有以下 Django 網址/視圖和模型:
模型.py:
ORDER_COLUMN_CHOICES = Choices(
('0', 'id'),
('1', 'code'),
('2', 'code_type'),
('3', 'created'),
('4', 'updated'),
('5', 'valid'),
)
class Identifier(TimeStampMixin, models.Model):
code_type = models.CharField(max_length=10, null=True)
code = models.CharField(max_length=12)
account = models.ForeignKey(Account, on_delete=models.CASCADE, null=True)
actflag = models.CharField(max_length=1, blank=True)
valid = models.BooleanField(default=False)
def __str__(self):
return self.code
class Meta:
db_table = "portfolio_identifier"
def query_identifier_by_args(**kwargs):
draw = int(kwargs.get('draw', None)[0])
length = int(kwargs.get('length', None)[0])
start = int(kwargs.get('start', None)[0])
search_value = kwargs.get('search[value]', None)[0]
order_column = kwargs.get('order[0][column]', None)[0]
order = kwargs.get('order[0][dir]', None)[0]
order_column = ORDER_COLUMN_CHOICES[order_column]
# django orm '-' -> desc
if order == 'desc':
order_column = '-' + order_column
queryset = Identifier.objects.all()
total = queryset.count()
if search_value:
queryset = queryset.filter(Q(id__icontains=search_value) |
Q(code__icontains=search_value) |
Q(code_type__icontains=search_value) |
Q(created__icontains=search_value) |
Q(updated__icontains=search_value) |
Q(valid__icontains=search_value))
count = queryset.count()
queryset = queryset.order_by(order_column)[start:start + length]
return {
'items': queryset,
'count': count,
'total': total,
'draw': draw
}
網址.py
from . import views
from rest_framework.routers import DefaultRouter
from apps.portfolio.views import IdentifierViewSet
router = DefaultRouter()
router.register(r'portfolio', IdentifierViewSet)
urlpatterns = [
path('portfolios/', views.portfolios, name="portfolios"),
path('portfolio/<str:pk>/', views.portfolio, name="portfolio"),
path('api/', include(router.urls)),
]
視圖.py
def portfolio(request, pk):
portfolio = Account.objects.get(id=pk)
identifiers = Identifier.objects.filter(account=pk)
context = {"portfolio": portfolio, "identifiers": identifiers}
return render(request, 'portfolio.html', context)
class IdentifierViewSet(viewsets.ModelViewSet):
queryset = Identifier.objects.all()
serializer_class = IdentifierSerializer
authentication_classes = []
def get_queryset(self):
account_pk = self.kwargs["pk"]
return super().get_queryset().filter(account=account_pk)
def list(self, request, **kwargs):
try:
identifier = query_identifier_by_args(**request.query_params)
serializer = IdentifierSerializer(identifier['items'], many=True)
result = dict()
result['data'] = serializer.data
result['draw'] = identifier['draw']
result['recordsTotal'] = identifier['total']
result['recordsFiltered'] = identifier['count']
return Response(result, status=status.HTTP_200_OK, template_name=None, content_type=None)
except Exception as e:
return Response(e, status=status.HTTP_404_NOT_FOUND, template_name=None, content_type=None)
在視圖中,我有一個基於 Class 的視圖IdentifierViewSet
,其中包含以下查詢集行queryset = Identifier.objects.all()
,它從數據庫 model 中檢索所有數據,但是我只想檢索基於與用戶帳戶關聯的投資組合的查詢集,這是有效的使用取自基於 function 的視圖portfolio
的以下代碼行:
portfolio = Account.objects.get(id=pk)
identifiers = Identifier.objects.filter(account=pk)
我無法將 pk 從 url 傳遞到這個基於 class 的視圖,但能夠使用基於 function 的視圖進行傳遞。
我 go 如何將上述 object 查詢傳遞到基於 Class 的視圖中,以替換基於 Class 的視圖queryset = Identifier.objects.all()
中的查詢集?
為此,您可以覆蓋 Django ModelViewSet 中的get_queryset
方法。
def get_queryset(self):
portfolio = Account.objects.get(id=self.request.account.pk)
#... do something
identifiers = Identifier.objects.filter(account=self.request.account.pk)
return identifiers
有list()
、 retrieve()
、 create()
、 update()
、 partial_update()
、 destroy()
函數, pk
參數可以傳遞給除list和create之外的四個函數。
例如API的PUT方法,可以自定義update
function。
class IdentifierViewSet(viewsets.ModelViewSet):
queryset = Identifier.objects.all()
serializer_class = IdentifierSerializer
authentication_classes = []
def list(self, request, *args, **kwargs):
...
def update(self, request, pk):
# you can get the pk here
print(pk)
# you can get the object with the current `pk`
instance = self.get_object()
...
您還可以像這樣自定義其他功能。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.