django-json-api/django-rest-framework-json-api

id column integer primary key of 0 gets returned as null

tonytony99 opened this issue · 2 comments

If a model has an id column that's an integer primary key

class Person(models.Model):
    id = models.IntegerField(primary_key=True)
    name = models.CharField(max_length=200)

and a fixture is loaded where the id has value 0

[
    {"model": "project.person", "fields": {"id": 0, "name": "Example"}},
    {"model": "project.person","fields": {"id": 1, "name": "Someone"}}
]

then the JSON response returned from the API replaces the id of 0 with null

    "data": [
        {
            "type": "person",
            "id": null,
            "attributes": {
                "name": "Example"
            }
        },
        {
            "type": "person",
            "id": "1",
            "attributes": {
                "name": "Someone"
            }
        }
    ],

@tonytony99 The issue you're encountering is likely due to the utility method
get_resource_id treating 0 as a falsy value, which results in it being replaced with None. This is why the id of 0 gets returned as null in the JSON response.

I'd say best to avoid using 0 as a primary key value and start with 1, if there may be cases where you need to support 0 as a valid id then following changes would result in 0 properly rendered in json response.

def get_resource_id(resource_instance, resource):
    """Returns the resource identifier for a given instance (`id` takes priority over `pk`).
    """
    # Check explicitly for None to allow 0 as a valid pk
    if resource and "id" in resource:
        return encoding.force_str(resource["id"]) if resource["id"] is not None else None
    if resource_instance:
        return (
            encoding.force_str(resource_instance.pk)
            if hasattr(resource_instance, "pk") and resource_instance.pk is not None
            else None
        )
    return None

Thanks for reporting. Feel free to work on a PR also containing a reproducing test to ensure we have the right fix and this remains. Potentially this is a regression of 6.1.0 but needs to be verified whether this issue occurs with version 6.0.0.