繁体   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