Django-filter: Campos de filtro são tecnicamente permitidos para todas as ações de visualização DRF. Isso mexe com o esquema CoreAPI.

Criado em 16 mai. 2018  ·  3Comentários  ·  Fonte: carltongibson/django-filter

Ao usar CoreAPI com DRF e DjangoFilterBackend habilitado, o cliente tenta mapear todos os campos para uma ação create, update ou partial_update para os parâmetros de consulta também. Isso interrompe a capacidade do cliente de usar esses métodos.

Exemplo

Se tivermos uma solicitação que tenta criar um livro com um nome e nome também for um campo filtrável em nosso modelo:

# book views
class BookViewSet():
    filter_fields = ('name',)
   # ...
// schema
client.action('book', 'create', { 'name': 'My Awesome Book' });

Isso criará uma solicitação com o nome no parâmetro de URL e o corpo da solicitação. Este não é o comportamento esperado.

POST /api/book?name=My%20Awesome%20Book

name=My Awesome Book

Solução proposta

Corrigimos isso em nosso código apontando nosso back-end de filtro DRF para uma substituição personalizada com o seguinte código:

class OnlyFilterOnReadDjangoFilterBackend(DjangoFilterBackend):
    """ A filter backend that only allows for filtering by properties on
    actions deemed as safe. This means that create, update, and partial_update
    actions will not provide filter options.
    """
    SAFE_ACTIONS = ('list', 'retrieve')

    def get_schema_fields(self, view):
        if view.action in self.SAFE_ACTIONS:
            return super().get_schema_fields(view)
        return []

Comentários muito úteis

Olá @Sonictherocketman. Obrigado pelo relatório.

Meu primeiro pensamento é que isso é um bug com a API do cliente - não é adequado distinguir entre os parâmetros da string de consulta e o corpo da solicitação ao construir a solicitação.

Em geral, apenas desabilitar a filtragem para ações não seguras não é correto. A filtragem ocorre ao estabelecer o conjunto de consultas base no qual uma atualização será feita.

Vou deixar isso em aberto por enquanto, só para pensar sobre isso.

Todos 3 comentários

Olá @Sonictherocketman. Obrigado pelo relatório.

Meu primeiro pensamento é que isso é um bug com a API do cliente - não é adequado distinguir entre os parâmetros da string de consulta e o corpo da solicitação ao construir a solicitação.

Em geral, apenas desabilitar a filtragem para ações não seguras não é correto. A filtragem ocorre ao estabelecer o conjunto de consultas base no qual uma atualização será feita.

Vou deixar isso em aberto por enquanto, só para pensar sobre isso.

Também acho que é um problema do cliente, mas quanto mais penso nisso, sinto que as ações não fazem sentido nas consultas de gravação (especialmente escrevendo para um recurso específico) e o esquema não deveria ter esses campos se eles não devem ser usados.

Obrigado pela resposta rápida e estou super interessado em seus pensamentos sobre isso.

Mais ou menos, acho que estamos limitados aqui por nossos desejos de geração de código _automágico_ superando a tecnologia (em seu estado atual).

Há muitas coisas que (ainda) não podemos fazer com esquemas (em qualquer um dos formatos disponíveis) que gostaríamos — por exemplo, com CoreAPI, ainda não podemos agrupar parâmetros para que um filtro de intervalo de datas seja exibido que eles estão relacionados. (Há muito mais que podemos fazer escrevendo esquemas à mão, mas ninguém quer fazer isso, é claro.)

Mas evolui, e à medida que o faz, o ferramental. Vai melhorar.

Que esta linha em particular:

client.action('book', 'create', { 'name': 'My Awesome Book' });

usa o mesmo dict para a string de consulta e o corpo da solicitação não é ótimo. Acho que é a abstração vazando. Você realmente quer construir esta solicitação _manualmente_, especificando parâmetros de consulta e corpo em lugares separados.

No momento, isso não é algo que possamos abordar aqui. Mais uma vez obrigado pelo relatório.

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

xtrinch picture xtrinch  ·  4Comentários

loganknecht picture loganknecht  ·  4Comentários

nhuzaa picture nhuzaa  ·  3Comentários

csarcom picture csarcom  ·  3Comentários

techdragon picture techdragon  ·  5Comentários