django-charid-field
django-charid-field copied to clipboard
examples to use other generator?
Is there an example on how to use cuid2 or nanoid? My assumption was passing a function that would return a generated id string would suffice but i keep getting weird errors, for ex: using cuid2:
ValueError: Could not find function cuid in cuid2.generator.
ValueError: Cannot serialize: <cuid2.generator.Cuid object at 0x1030071d0>
using nanoid:
default=nanoid.generate.generate, ^^^^^^^^^^^^^^^^^^^^^^^^ AttributeError: 'function' object has no attribute 'generate'
Hi @hyusetiawan.
Internally we use it with cuid v1 like this:
from functools import partial
from charidfield import CharIDField
from cuid import cuid as generate_cuid
CuidField = partial(
CharIDField,
max_length=40,
default=generate_cuid,
help_text=_("A cuid spec public identifier"),
)
And then we import CuidField into a model and use it as we see fit.
generate_cuid is the function which generates the ID string.
So for nanoid (assuming from pypi), it would be:
from functools import partial
from charidfield import CharIDField
from nanoid import generate as generate_nanoid
NanoIDField = partial(
CharIDField,
max_length=40,
default=generate_nanoid,
help_text=_("A nanoid spec public identifier"),
)
And for cuid2 (again, assuming from pypi), it would be:
from functools import partial
from charidfield import CharIDField
from cuid2 import cuid2_wrapper
cuid2_generator = cuid2_wrapper()
CuidID2Field = partial(
CharIDField,
max_length=40,
default=cuid2_generator,
help_text=_("A cuid2 spec public identifier"),
)
This is not checked - it's just based on both of their respective documentation.
Let me know how you get on and we can update the docs.
@djm thank you for the thorough response, unfortunately it's still not working for cuid2, here is my code snippet:
from functools import partial
from charidfield import CharIDField
from cuid2 import cuid_wrapper
cuid_generator = cuid_wrapper()
CuidField = partial(
CharIDField,
default=cuid_generator,
max_length=40, # type: ignore
unique=True,
help_text="global id.",
)
here is the error:
ValueError: Could not find function cuid in cuid2.generator.
note: it's cuid_wrapper not cuid2_wrapper, at least for the latest cuid2 i installed
@djm bump + happy new year :D
I'm also running into this
One workaround, for the moment, is to use the "direct instantiation" approach:
from functools import partial
from charidfield import CharIDField
from cuid2 import Cuid
from django.utils.translation import gettext_lazy as _
CUID_GENERATOR: Cuid = Cuid()
CuidField = partial(
CharIDField,
default=CUID_GENERATOR.generate,
max_length=40,
help_text=_("cuid2-format identifier for this entity."),
)
The migration doesn't seem to be using the local generator though:
migrations.AddField(
model_name="smartgoal",
name="public_id",
field=charidfield.fields.CharIDField(
default=cuid2.generator.Cuid.generate,
help_text="cuid2-format identifier for this entity.",
max_length=40,
prefix="sg_",
unique=True,
),
),
Well, that doesn't work. Back to the drawing board!
from functools import partial
from charidfield import CharIDField
from cuid2 import Cuid
cuid_generator = Cuid()
def generate_cuid():
return cuid_generator.generate()
CUIDField = partial(
CharIDField,
default=generate_cuid,
max_length=40,
help_text="CUID field",
editable=False,
verbose_name="CUID",
)
thats how it works
@ReDev1L what happens if you add that field that to a model with existing rows?
You would need to add it as nullable, back-populate, and then make the field non-null after. This is (unfortunately) the standard way to add a no-downtime column to any populated table, it is a bit of a faff but it gets the job done.
So you could have that CUIDField partial defined as they did, and then:
class SomeModel(models.Model):
a_cuid2_field = CUIDField(null=True)
Then create migration and release.
Back-populate via a method of your choosing (we do it with a management command).
Then remove the null=True and create another migration.
Release that, and then you're in the new world.
Remember, all the partial is doing is supplying some defaults - you can still override them by passing new params in :)
Sorry for missing the original replies on this thread, we have been a tad busy.