Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error in generating schema for GeoDjango models #694

Open
gurbaaz27 opened this issue Mar 6, 2023 · 2 comments
Open

Error in generating schema for GeoDjango models #694

gurbaaz27 opened this issue Mar 6, 2023 · 2 comments

Comments

@gurbaaz27
Copy link

gurbaaz27 commented Mar 6, 2023

Please describe what you are trying to achieve
I have a Django model with a location field (which is a PointField), and I am trying to generate schema from it using ModelSchema, but I guess django-ninja doesn't have support for these geofields. I wanted to know if I am doing an error, or is there any hack around the same? Thanks.

Please include code examples (like models code, schemes code, view function) to help understand the issue

models.py

from django.db import models
from django.contrib.gis.db import models as geomodels
from django.utils.translation import gettext_lazy as _

from uuid import uuid4

# Create your models here.
class Store(models.Model):
    id = models.UUIDField(_("ID"), primary_key=True, editable=False, default=uuid4) 
    name = models.CharField(_("Name"), max_length=200)
    location = geomodels.PointField(_("Location"), geography=True, srid=4326, blank=True, null=True)
    description = models.TextField(_("Description"), null=True, blank=True)
    contact_info = models.JSONField(_("Contact Information"), null=True)

schema.py

from ninja import ModelSchema
from stores.models import Store

class StoreSchema(ModelSchema):
    class Config:
        model = Store
        models_fields = "__all__"

Error

Watching for file changes with StatReloader
Performing system checks...

Exception in thread django-main-thread:
Traceback (most recent call last):
  File "/usr/lib/python3.10/threading.py", line 1016, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.10/threading.py", line 953, in run
    self._target(*self._args, **self._kwargs)
  File "/home/gurbaaz/servlog-backend/venv/lib/python3.10/site-packages/django/utils/autoreload.py", line 64, in wrapper
    fn(*args, **kwargs)
  File "/home/gurbaaz/servlog-backend/venv/lib/python3.10/site-packages/django/core/management/commands/runserver.py", line 134, in inner_run
    self.check(display_num_errors=True)
  File "/home/gurbaaz/servlog-backend/venv/lib/python3.10/site-packages/django/core/management/base.py", line 475, in check
    all_issues = checks.run_checks(
  File "/home/gurbaaz/servlog-backend/venv/lib/python3.10/site-packages/django/core/checks/registry.py", line 88, in run_checks
    new_errors = check(app_configs=app_configs, databases=databases)
  File "/home/gurbaaz/servlog-backend/venv/lib/python3.10/site-packages/django/core/checks/urls.py", line 14, in check_url_config
    return check_resolver(resolver)
  File "/home/gurbaaz/servlog-backend/venv/lib/python3.10/site-packages/django/core/checks/urls.py", line 24, in check_resolver
    return check_method()
  File "/home/gurbaaz/servlog-backend/venv/lib/python3.10/site-packages/django/urls/resolvers.py", line 494, in check
    for pattern in self.url_patterns:
  File "/home/gurbaaz/servlog-backend/venv/lib/python3.10/site-packages/django/utils/functional.py", line 57, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/home/gurbaaz/servlog-backend/venv/lib/python3.10/site-packages/django/urls/resolvers.py", line 715, in url_patterns
    patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
  File "/home/gurbaaz/servlog-backend/venv/lib/python3.10/site-packages/django/utils/functional.py", line 57, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/home/gurbaaz/servlog-backend/venv/lib/python3.10/site-packages/django/urls/resolvers.py", line 708, in urlconf_module
    return import_module(self.urlconf_name)
  File "/usr/lib/python3.10/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 883, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "/home/gurbaaz/servlog-backend/servlog/servlog/urls.py", line 20, in <module>
    from stores.api import router as stores_router
  File "/home/gurbaaz/servlog-backend/servlog/stores/api.py", line 12, in <module>
    from stores.schema import LocationQuerySchema, StoreSchema
  File "/home/gurbaaz/servlog-backend/servlog/stores/schema.py", line 16, in <module>
    class StoreSchema(ModelSchema):
  File "/home/gurbaaz/servlog-backend/venv/lib/python3.10/site-packages/ninja/orm/metaclass.py", line 62, in __new__
    model_schema = create_schema(
  File "/home/gurbaaz/servlog-backend/venv/lib/python3.10/site-packages/ninja/orm/factory.py", line 56, in create_schema
    python_type, field_info = get_schema_field(fld, depth=depth)
  File "/home/gurbaaz/servlog-backend/venv/lib/python3.10/site-packages/ninja/orm/fields.py", line 130, in get_schema_field
    python_type = TYPES[internal_type]
KeyError: 'PointField'
@OtherBarry
Copy link
Contributor

You might need to make a custom class for points, like this.

@gurbaaz27
Copy link
Author

@OtherBarry thanks for the resource.

Right now I am extending TYPES like this. Is this the correct way to do?

from ninja.orm.fields import TYPES

from stores.models import Store

class PointClass(Point):
    @classmethod
    def __get_validators__(cls):
        yield cls.validate

    @classmethod
    def validate(cls, v):
        return cls(v)

    @classmethod
    def __modify_schema__(cls, field_schema):
        field_schema.update(type="tuple", example=(22.5, 22.5))

    def __repr__(self):
        return f"PointField({super().__repr__()})"


TYPES.update({"PointField": PointClass})

class StoreSchema(ModelSchema):
    class Config:
        model = Store
        model_fields = "__all__"

I haven't tested the API, but running the server doesn't throw any error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants