Coder Social home page Coder Social logo

mariocesar / django-ltree Goto Github PK

View Code? Open in Web Editor NEW
60.0 1.0 15.0 105 KB

An ltree extension implementation to support hierarchical tree-like data using the native Postgres extension ltree in django models

Home Page: https://pypi.org/project/django-ltree/

License: MIT License

Python 93.79% Makefile 0.89% Dockerfile 5.32%
django ltree postgresql-extension

django-ltree's Introduction

django-ltree

A tree extension implementation to support hierarchical tree-like data in Django models, using the native Postgres extension ltree.

Postgresql has already a optimized and very useful tree implementation for data. The extension is ltree

This fork contains a backport to Django 1.11 and Python 3.6.

Test

Links

Install

pip install django-ltree

Then add django_ltree to INSTALLED_APPS in your Django project settings.

And make sure to run django_ltree migrations before you added the PathField

python manage.py migrate django_ltree

django_ltree migrations will install the ltree extension if not exist.

You can alternatively specify the django_ltree dependency in the migrations of your applications that requires PathField, and run migrations smoothly.

class Migration(migrations.Migration):
    dependencies = [
            ('django_ltree', '__latest__'),
    ]

Requires

  • Django 1.11 or superior
  • Python 2

Testing

Make sure you have Postgres installed. Then simply run tox in the root directory of the project.

django-ltree's People

Contributors

bctcvai avatar boryszef avatar mariocesar avatar opentyler avatar ovangle avatar ramonsaraiva avatar thomaspinna avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

django-ltree's Issues

NLevel transform is not registered as a lookup

Currently, the NLevel transform (functions.py) is not registered as a lookup. This means, that queries like MyModel.objects.filter(path__depth=NLevel(self.path)) won't work:

Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "C:\Users\user\.virtualenvs\backend-BawPrnSu\lib\site-packages\django\db\models\manager.py", line 82, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "C:\Users\user\.virtualenvs\backend-BawPrnSu\lib\site-packages\django\db\models\query.py", line 892, in filter
    return self._filter_or_exclude(False, *args, **kwargs)
  File "C:\Users\user\.virtualenvs\backend-BawPrnSu\lib\site-packages\django\db\models\query.py", line 910, in _filter_or_exclude
    clone.query.add_q(Q(*args, **kwargs))
  File "C:\Users\user\.virtualenvs\backend-BawPrnSu\lib\site-packages\django\db\models\sql\query.py", line 1290, in add_q
    clause, _ = self._add_q(q_object, self.used_aliases)
  File "C:\Users\user\.virtualenvs\backend-BawPrnSu\lib\site-packages\django\db\models\sql\query.py", line 1318, in _add_q
    split_subq=split_subq, simple_col=simple_col,
  File "C:\Users\user\.virtualenvs\backend-BawPrnSu\lib\site-packages\django\db\models\sql\query.py", line 1251, in build_filter
    condition = self.build_lookup(lookups, col, value)
  File "C:\Users\user\.virtualenvs\backend-BawPrnSu\lib\site-packages\django\db\models\sql\query.py", line 1110, in build_lookup
    lhs = self.try_transform(lhs, lookup_name)
  File "C:\Users\user\.virtualenvs\backend-BawPrnSu\lib\site-packages\django\db\models\sql\query.py", line 1151, in try_transform
    "permitted%s" % (name, output_field.__name__, suggestion)
django.core.exceptions.FieldError: Unsupported lookup 'depth' for PathField or join on the field not permitted.

Registering the lookup before running the query fixes this:
PathField.register_lookup(NLevel)

Is there a reason why this is missing?

Django 2.2.6
Python 3.6.5
django-ltree 0.4

Compatibility with Django3

Hi there!

Thanks for creating this extension :)

I encountered an issue when updating our project to Django3 (Python: 3.6, Django: 3.0.3).

I don't use the querysets methods directly, but rather the lookups:

units = Unit.objects.filter(path__descendants=path)  # path is an instance of PathValue

It used to work fine, but since our migration to Django3, we get the following issue:

  File "/usr/local/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1074, in resolve_lookup_value
    for sub_value in value
  File "/usr/local/lib/python3.6/site-packages/django_ltree/fields.py", line 15, in __init__
    raise ValueError("Invalid value for path: {}".format(val))
ValueError: Invalid value for path: <generator object Query.resolve_lookup_value.<locals>.<genexpr> at 0x7fbeedd42d00>

The "culprit" is this line: https://github.com/django/django/blob/master/django/db/models/sql/query.py#L1067

As PathValue extends list, in the above code, it is instantiated with a generator object, which is not accepted by PathValue constructor.

For now, as a workaround, I cast all paths to string before using them in my queries, which seems to work quite well, but being able to use PathValue instances was rather practical.

I would be happy to work on a PR to fix this issue, but I'm not sure what would be the best way to proceed:

  • Stop extending list?
  • Allowing a generator object in PathValue constructor?

Let me know if I can help!

PathValue should be usable in dict and set

When dealing with trees, it's quite common to use a dictionary to label nodes, using the path as the key. Currently this can be accomplished by casting the path to str, but this introduces a lot of unnecessary casts.

Ideally, PathValue should extend tuple instead of list, but since this would be a breaking change, perhaps it's better to implement __hash__ on PathValue?

I'd imagine most code would treat paths as immutable anyway.

Thoughts?

I'd be happy to submit a PR implementing whatever you decide is the best course of action.

Possible bug at this line where str should be value in `"/" if "/" in str else "."`

Over in this line

split_by = "/" if "/" in str else "."

When i run python3.7 this doesn't seem to trigger any issue but when I upgrade to python3.8 in my django app, I get this error.

File "/usr/local/lib/python3.8/dist-packages/django_ltree/fields.py", line 13, in __init__
    split_by = "/" if "/" in str else "."
TypeError: argument of type 'type' is not iterable

Admin panel doesnot work with paths that start with an integer

Hi,

The regex pattern in

path_label_validator = RegexValidator(
r"^(?P<root>[a-zA-Z][a-zA-Z0-9_]*)(?:.[a-zA-Z|a-zA-Z0-9_]+)*$",
"A label is a sequence of alphanumeric characters and underscores separated by dots.",
"invalid",
)

Is not right.

It matches things like exampleIdentifier.group1.group2.group3 but not 0001.0000.000a ( which is the default generated paths for django-ltree )

In order to solve this change the regex to (?P<root>[a-zA-Z][a-zA-Z0-9_]*|\d+)(?:\.[a-zA-Z0-9_]+)*$ which accepts paths starting with an integer.

Thanks a bunch :D

more documentation on how to use this library better?

I have this exact code snippet and the migration is successful.

from core.models import PersonStampedModel
from django_ltree.fields import PathField
from model_utils.models import SoftDeletableModel, TimeStampedModel
from organizations.managers import OrganizationOwnedSoftDeletableManager
from organizations.models import OrganizationOwnedModel
from partial_index import PQ, PartialIndex


class WorkBreakdownStructure(
    TimeStampedModel, SoftDeletableModel, PersonStampedModel, OrganizationOwnedModel
):
    wbs_number = PathField(primary_key=True, editable=True)

    objects = OrganizationOwnedSoftDeletableManager()

    unique_field_in_organization = "wbs_number"

    def __str__(self):
        return str(self.wbs_number)

    class Meta:
        indexes = [
            PartialIndex(
                fields=["wbs_number", "organization"], unique=True, where=PQ(is_removed=False)
            )
        ]

I wanted to quickly bulk create the following records:

ABC20.12345.50000 - ABC20.12345.51000

I was wondering if there's some documentation on how to do this.

versions

Django: v2.2.9
Python: v3.6
postgres: v10

Hard fork at `django-ltree-2`

Hi,

I don't think this repository is in development anymore, I have a fork at django-ltree-2 which addresses :

Along with some new features available in python :

Along with automatic label generation

Along with documentation

The test suits are identical. The project is a drop in replacement for django-ltree.

I am open to collaborations, if django-ltree is open to development, I will archive the fork.

Thanks a bunch

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.