Coder Social home page Coder Social logo

Comments (4)

dantownsend avatar dantownsend commented on September 23, 2024 1

@sinisaos Hmmm, actually it might not be so easy to move that logic into a separate method. Don't worry about that for now.

from piccolo_api.

sinisaos avatar sinisaos commented on September 23, 2024

@dantownsend We can make this to work with these two changes. We need to change _pydantic_model_output to this

def _pydantic_model_output(
      self,
      include_readable: bool = False,
      include_columns: t.Tuple[Column, ...] = (),
      nested: t.Union[bool, t.Tuple[Column, ...]] = False,
) -> t.Type[pydantic.BaseModel]:
    return create_pydantic_model(
        self.table,
        include_default_columns=True,
        include_readable=include_readable,
        include_columns=include_columns,
        model_name=f"{self.table.__name__}Output",
        nested=nested,
    )

and then we need to change get_single to this

@apply_validators
async def get_single(self, request: Request, row_id: int) -> Response:
    """
    Returns a single row.
    """
    params = dict(request.query_params)
    split_params: Params = self._split_params(params)
    try:
        columns: t.Sequence[Selectable] = self.table._meta.columns
        if split_params.include_readable:
            readable_columns = [
                self.table._get_related_readable(i)
                for i in self.table._meta.foreign_key_columns
            ]
            columns = [*columns, *readable_columns]

        nested: t.Union[bool, t.Tuple[Column, ...]]

        # Visible fields
        visible_fields = split_params.visible_fields
        if visible_fields:
            column_names: t.List[str] = visible_fields.split(",")
            visible_columns: t.List[Column] = []

            try:
                for column_name in column_names:
                    column = self.table._meta.get_column_by_name(
                        column_name
                    )

                    if len(column._meta.call_chain) > self.max_joins:
                        return Response(
                            "Max join depth exceeded", status_code=400
                        )
                    else:
                        visible_columns.append(column)
            except ValueError as exception:
                # If we can't find a column with that name.
                return Response(str(exception), status_code=400)

            nested = tuple(
                i for i in visible_columns if len(i._meta.call_chain) > 0
            )
        else:
            visible_columns = self.table._meta.columns
            nested = False

        columns = [*columns, *visible_columns]

        query = (
            self.table.select(
                *columns,
                exclude_secrets=self.exclude_secrets,
            )
            .where(self.table._meta.primary_key == row_id)
            .first()
        )

        # Make it nested if required
        if nested:
            row = await query.output(nested=True).run()
        # else return all fields
        row = await query.run()

    except ValueError:
        return Response(
            "Unable to find a resource with that ID.", status_code=404
        )

    return CustomJSONResponse(
        self._pydantic_model_output(
            include_readable=split_params.include_readable,
            include_columns=tuple(visible_columns),
            nested=nested,
        )(**row).json()
    )

If you agree with these changes I can do PR.

from piccolo_api.

dantownsend avatar dantownsend commented on September 23, 2024

@sinisaos Yes, that looks good - thanks.

It's probably worth moving his logic out into a separate method:

column_names: t.List[str] = visible_fields.split(",")
columns: t.List[Column] = []
try:
for column_name in column_names:
column = self.table._meta.get_column_by_name(column_name)
if len(column._meta.call_chain) > self.max_joins:
return Response(
"Max join depth exceeded", status_code=400
)
else:
columns.append(column)
except ValueError as exception:
# If we can't find a column with that name.
return Response(str(exception), status_code=400)
nested = tuple(i for i in columns if len(i._meta.call_chain) > 0)
else:
columns = self.table._meta.columns
nested = False

So we can use it in the root and detail endpoints without repeating ourselves.

from piccolo_api.

dantownsend avatar dantownsend commented on September 23, 2024

Fixed by #112

from piccolo_api.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.