簡體   English   中英

如何將基於 class 的視圖中的 pk 參數傳遞給 Django 中的查詢集

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM