dabapps / django-readers

A lightweight function-oriented toolkit for better organisation of business logic and efficient selection and projection of data in Django projects.
https://www.django-readers.org
BSD 2-Clause "Simplified" License
186 stars 7 forks source link

When i use project, the decimal value shows up as Decimal('1.00') how do i make all decimal show up as '1.00' str? #62

Closed simkimsia closed 2 years ago

simkimsia commented 2 years ago

related to #60

def get_product_package_details_by_id(pk):
    """
    get product package by id for details
    """
    spec_for_pp_line_items = [
        "id",
        {
            "product": [
                "description_in_mus",
                "description_sow",
                "id",
                "product_number",
                "unit",
            ]
        },
        "quantity"
    ]
    spec = [
        "id",
        "name",
        {
            "product_package_line_items": spec_for_pp_line_items
        },
    ]

    prepare, project = specs.process(spec)
    product_package = prepare(ProductPackage.objects.all()).get(pk=pk)

    return project(product_package)

the quantity shows up as Decimal('1.00') how do i make it become '1.00' string?

simkimsia commented 2 years ago

I saw this

project = projectors.combine(
    projectors.producer_to_projector("name", producers.attr("name")),
    projectors.producer_to_projector("age", produce_age),
    projectors.producer_to_projector(
        "book_set",
        producers.relationship(
            "book_set",
            projectors.combine(
                projectors.producer_to_projector("title", producers.attr("title")),
                projectors.producer_to_projector(
                    "publication_year",
                    producers.attr("publication_year"),
                ),
            ),
        ),
    ),
)

Does this mean i need to repeat the specs and one by one state the projector? Is there a simpler way? i only care about quantity in my case.

j4mie commented 2 years ago

It depends what you want to do with your projected result dictionary. If you're building an API and so using Django REST framework or using Django's JSONResponse, the encoder will do this for you. If you really want to do it yourself, you can replace just that field name in the spec with the corresponding pair function and use the transform_value argument, like this:

from django_readers import pairs

spec_for_pp_line_items = [
    "id",
    {
        "product": [
            "description_in_mus",
            "description_sow",
            "id",
            "product_number",
            "unit",
        ]
    },
    {"quantity": pairs.field("quantity", transform_value=str)}
]
simkimsia commented 2 years ago

If you're building an API and so using Django REST framework or using Django's JSONResponse, the encoder will do this for you

I am not. I am using django template and passing in the context and there's a javascript that needs to take in the str version of decimal.

This is great. Thank you. @j4mie

You should add this note about encoder for DRF and example for decimal in the readme.

j4mie commented 2 years ago

@simkimsia you could also do this in the template with intcomma

You should add this note about encoder for DRF and example for decimal in the readme.

Currently (very) slowly working on proper docs in #59