簡體   English   中英

如何在DRF viewsets.ModelViewSet中查詢相關object

[英]How to query related object in DRF viewsets.ModelViewSet

我有一個與數據表一起使用的序列化 model (Job)。 “工作” model 與另一個 model(板)相關,這就是我的問題所在。 我按照此處的文檔過濾了與當前正在查看的“板”model 相關的作業,但我無法讓它按預期工作。

models.py

class Board(models.Model):
    name = models.CharField(_('board name'), max_length=256)
    slug = models.SlugField(_('unique url'), null=True, blank=True)
...


class Job(models.Model):
    board = models.ForeignKey(Board, on_delete=models.CASCADE, verbose_name=_('board'))
...

views.py

 class JobDataTablesViewSet(viewsets.ModelViewSet):
        queryset = Job.objects.all().order_by('-date_posted')
        serializer_class = JobDatatablesSerializer
        filter_backends = (DatatablesFilterBackend,)
        filterset_class = JobGlobalFilter
    
        def get_queryset(self):
            slug = self.kwargs['slug']
            queryset = Job.objects.filter(board__slug=slug)
            return queryset

urls.py

path('<slug:slug>/', views.BoardPublicView.as_view(), name='public-board')

您必須為ForeignKey查找提供__ 因此, get_queryset方法如下:

slug = models.SlugField(
    unique=True,
    default=self.slug, # This is not from the tutorial, it's a modification
    # to demonstrate here.
    max_length=13,
)

def get_queryset(self):
    slug = self.kwargs['slug']
    queryset = Job.objects.filter(board__slug=slug)
    return queryset

對於有類似問題的任何人,請查看alanjds/drf-nested-routers 這就是我使用的,並且效果很好。

這是我所做的概述。

安裝 package 和pip install drf-nested-routers

根據文檔,

不需要在 Django 項目的 settings.py 文件中添加此庫,因為它不包含任何應用程序、信號或 model。

在我的應用程序urls.py文件中,我創建了父路由器和子路由器

router = routers.SimpleRouter()
router.register(r'boards', views.BoardViewSet, basename="boards_api_list")

boards_router = routers.NestedSimpleRouter(router, r'boards', lookup='board')
boards_router.register(r'jobs', views.JobViewSet, basename='board_jobs_list')

urlpatterns = [
    path('api/', include(router.urls)),
    path('api/', include(boards_router.urls)),
]

然后在我的serializers.py中,我創建了一個HyperlinkedModelSerializer

class BoardSerializer(serializers.HyperlinkedModelSerializer):
    owner = UserSerializer()
    jobs = NestedHyperlinkedRelatedField(
        many=True,
        read_only=True,
        view_name='jobs_view_name',
        parent_lookup_kwargs={'slug': 'board__slug'}
    )

    class Meta:
        model = Board
        fields = [...]
        extra_kwargs = {
            'url': {'view_name': 'my_custom_view_name', 'lookup_field': 'slug'},
            ...other desired kwargs...
        }

class JobViewSet(serializers.ModelSerializer):
    ...standard serializer settings...

我繼續我的views.py來創建我的視圖集並添加了get_queryset參數

class JobViewSet(viewsets.ModelViewSet):
    queryset = Job.objects.all().order_by('-date_posted')
    serializer_class = JobSerializer
    filter_backends = (DatatablesFilterBackend,)
    filterset_class = JobGlobalFilter

    def get_queryset(self):
        return Job.objects.filter(board__slug=self.kwargs['board_slug'])

完成這些操作后,您應該能夠通過以下方式訪問您的 API

/parent_url/{{parent_pk}}/child_list/{{child_pk}}

現在,由於我的特殊需要(我想在數據表上使用它來過濾相關對象),我將我的 API 的 URL 添加到我的base.html的頭部,以便可以動態加載 URL,因為我無法加載在我的 javascript 文件中

...
<head>
    <script>var boardListUrl= "{% url 'boards:boards_api_list-list' %}?format=datatables"</script>
    {% if board.slug %}
    <script>var jobListUrl= "{% url 'boards:board_jobs_list-list' board.slug %}?format=datatables"</script>
    {% endif %}
<head>
...

在我的main.py文件中,我做了以下

 var table = $('#tableName').DataTable({
        ...
        "ajax": jobListUrl,
        ...
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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