django rest数据表,通过满足目标筛选专家

django rest数据表,通过满足目标筛选专家,django,django-rest-framework,datatables,django-rest-framework-datatables,Django,Django Rest Framework,Datatables,Django Rest Framework Datatables,我需要根据过去的目标筛选所有专家 我有一个最小的可运行示例(顺便说一句,您可以用测试数据加载一些装置) 我的模特是 class Expert(models.Model): name = models.CharField(blank=True, max_length=300) class Meeting(models.Model): user = models.ForeignKey(User, on_delete=models.SET_NULL, blank=True, nul

我需要根据过去的目标筛选所有专家

我有一个最小的可运行示例(顺便说一句,您可以用测试数据加载一些装置)

我的模特是

class Expert(models.Model):
    name = models.CharField(blank=True, max_length=300)


class Meeting(models.Model):
    user = models.ForeignKey(User, on_delete=models.SET_NULL, blank=True, null=True)
    expert = models.ForeignKey(Expert, on_delete=models.SET_NULL, blank=True, null=True)
    objective = models.TextField(null=True, blank=True)
我的数据表javascript

$("#table-analyst-search").DataTable({
  serverSide: true,
  ajax: "/api/experts/?format=datatables",
  ordering: false,
  pagingType: "full_numbers",
  responsive: true,
  columns: [
    {
      data: "objectives",
      name: "objectives",
      visible: false,
      searchable: true,
      render: (objectives, type, row, meta) => {
        return objectives;
      }
    },
  ],
});
我的序列化程序

class ExpertSerializer(serializers.ModelSerializer):
    id = serializers.IntegerField(read_only=True)
    objectives = serializers.SerializerMethodField()

    class Meta:
        model = Expert
        fields = (
            "id",
            "objectives",
        )


    def get_objectives(self, obj):
        request = self.context["request"]
        request = self.context["request"]
        meetings = Meeting.objects.filter(
            analyst_id=request.user.id, expert_id=obj.id
        ).distinct('objective')
        if len(meetings) > 0:
            objectives = meetings.values_list("objective", flat=True)
            objectives = [x for x in objectives if x]
        else:
            objectives = []
        return objectives
当我开始在datatables.js搜索栏中输入数据时,会出现如下错误

FieldError at /api/experts/
Cannot resolve keyword 'objectives' into field. Choices are: bio, company, company_id, created_at, description, email, favoriteexpert, first_name, id, is_blocked, last_name, meeting, middle_name, network, network_id, position, updated_at

Request Method: GET
Request URL: http://localhost:8000/api/experts/?format=datatables&draw=3&columns%5B0%5D%5Bdata%5D=tags&columns%5B0%5D%5Bname%5D=favoriteexpert.tags.name&columns%5B0%5D%5Bsearchable%5D=true&columns%5B0%5D%5Borderable%5D=false&columns%5B0%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B0%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B1%5D%5Bdata%5D=desc&columns%5B1%5D%5Bname%5D=&columns%5B1%5D%5Bsearchable%5D=false&columns%5B1%5D%5Borderable%5D=false&columns%5B1%5D%5Bsearch%5D%5Bvalue%5D=&columns%
fwiw,在纯django orm中,我想要实现的是

Expert.objects.filter(
    pk__in=Meeting.objects.filter(
        objective__icontains='Plastics', user=request.user
    ).values('expert')
)
如何根据历史会议目标筛选专家


错误的原因是
django rest framework datatables
试图将请求转换为可针对
Expert
表运行的查询

在JS中,您要求返回一个名为“目标”的字段,但是
Expert
模型中没有这样的字段

您可能会使用。在这种情况下,您可以在对会议的FK引用上设置一个过滤器。演示了如何执行此操作

我认为理解发生了什么的最好方法是让示例应用程序运行,如果可能的话,设置断点并逐步执行


顺便说一句,如果您想让搜索框正常工作,那么您需要定义一个
global\u q()
方法。示例应用程序中也介绍了这一点。

出现错误的原因是,
django rest framework datatables
试图将请求转换为可针对
Expert
表运行的查询

在JS中,您要求返回一个名为“目标”的字段,但是
Expert
模型中没有这样的字段

您可能会使用。在这种情况下,您可以在对会议的FK引用上设置一个过滤器。演示了如何执行此操作

我认为理解发生了什么的最好方法是让示例应用程序运行,如果可能的话,设置断点并逐步执行


顺便说一句,如果您想让搜索框正常工作,那么您需要定义一个
global\u q()
方法。示例应用程序中也介绍了这一点。

我最终编写了一个自定义django过滤器

class AssociatedMeetingCharFilter(filters.CharFilter):
    def global_q(self):
        """
        Uses the global filter to search a meeting field of meetings owned by the logged in user
        """
        if not self._global_search_value:
            return Q()
        kw = "meeting__{}__{}".format(self.field_name, self.lookup_expr)
        return Q(**{
            kw: self._global_search_value,
            "meeting__user_id": self.parent.request.user.id or -1,
        })


class ExpertGlobalFilterSet(DatatablesFilterSet):
    name = GlobalCharFilter(lookup_expr='icontains')
    objectives = AssociatedMeetingCharFilter(field_name='objective', lookup_expr='icontains')

完整示例在

我最终创作了一个自定义django过滤器

class AssociatedMeetingCharFilter(filters.CharFilter):
    def global_q(self):
        """
        Uses the global filter to search a meeting field of meetings owned by the logged in user
        """
        if not self._global_search_value:
            return Q()
        kw = "meeting__{}__{}".format(self.field_name, self.lookup_expr)
        return Q(**{
            kw: self._global_search_value,
            "meeting__user_id": self.parent.request.user.id or -1,
        })


class ExpertGlobalFilterSet(DatatablesFilterSet):
    name = GlobalCharFilter(lookup_expr='icontains')
    objectives = AssociatedMeetingCharFilter(field_name='objective', lookup_expr='icontains')
完整示例