Skip to content

Commit 1b045b3

Browse files
committed
Skip the automatic unique index setting
1 parent 7249685 commit 1b045b3

File tree

4 files changed

+24
-5
lines changed

4 files changed

+24
-5
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ class Dog(models.Model):
113113
|**prefix**|`str` ||`""`|If provided, the ID strings generated as the field's default value will be prefixed. This provides a way to have a per-model prefix which can be helpful in providing a global namespace for your ID system. The prefix should be provided as a string literal (e.g `cus_`). For more, see below.|
114114
|**max_length**|`int`||Set it|Controls the maximum length of the stored strings. Provide your own to match whatever ID system you pick, remembering to take into account the length of any prefixes you have configured. Also note that there is no perf/storage impact for modern Postgres so for that backend it is effectively an arbitary char limit.|
115115
|**primary_key**|`boolean`||`False`|Set to `True` to replace Django's default `Autofield` that gets used as the primary key, else the field will be additional ID field available to the model.|
116-
|**unique**|`boolean`||`True`|Whether the field should be treated as unique across the dataset; the field provides a sane default of `True` so that a database index is setup to protext you against collisions (whether due to chance or, more likely, a bug/human error). To turn the index off, simply pass `False`.|
116+
|**unique**|`boolean`|❌|`False`|Whether the field should be treated as unique across the dataset; when `primary_key=True`, unique is implied. Behave the same as in `django.do.models.fields.CharField`.
117117

118118
All other `django.db.models.fields.CharField` keyword arguments should work as expected. See the [Django docs](https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.CharField).
119119

charidfield/fields.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,6 @@ def __init__(
4242
else:
4343
kwargs["default"] = default
4444

45-
# Ensure a unique index is set up by default unless the caller
46-
# explicitly disables it; this seems like the sane thing to do.
47-
kwargs.setdefault("unique", True)
48-
4945
super().__init__(*args, **kwargs)
5046

5147
def get_internal_type(self) -> str:

tests/models.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ class IDModel(models.Model):
4141
# Showcase the default field but without an index.
4242
no_index_id = TestUIDField(unique=False)
4343

44+
# Showcase setting unique explicitly.
45+
unique_id = TestUIDField(unique=True)
46+
4447
# Showcase with a static default + a prefix. This is very much an edge
4548
# case as I can't think of a good reason to ever want a static default
4649
# for an ID field, but given you can call it like this: we should test it.

tests/test_fields.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ def test_setting_primary_key(self):
210210
# object will not persist.
211211
self.instance_a.default_id = generate_test_uid()
212212
self.instance_a.prefixed_id = generate_test_uid(prefix="dev_")
213+
self.instance_a.unique_id = generate_test_uid()
213214
self.instance_a.save()
214215
self.instance_a.refresh_from_db()
215216
assert self.instance_a.id == new_id
@@ -244,6 +245,23 @@ def test_setting_non_primary_key(self, model_field_name):
244245
if old_id:
245246
assert IDModel.objects.filter(**{model_field_name: old_id}).count() == 0
246247

248+
@pytest.mark.parametrize(
249+
"model_field_name, expected",
250+
(
251+
("id", True),
252+
("unique_id", True),
253+
("default_id", False),
254+
("prefixed_id", False),
255+
("null_id_with_no_default", False),
256+
("not_null_id_but_blank", False),
257+
("no_index_id", False),
258+
("prefixed_and_non_callable_default_id", False),
259+
),
260+
)
261+
def test_unique_set_default(self, model_field_name, expected):
262+
field = self.instance_a._meta.get_field(model_field_name)
263+
assert field.unique is expected
264+
247265
def test_foreign_key__with_parent_model__instance(self):
248266
related_instance = RelatedIDModel.objects.create(
249267
name="Blue Album", parent=self.instance_a
@@ -277,6 +295,7 @@ def test_dumpdata(self):
277295
"null_id_with_no_default": None,
278296
"not_null_id_but_blank": "",
279297
"no_index_id": self.instance_a.no_index_id,
298+
"unique_id": self.instance_a.unique_id,
280299
"prefixed_and_non_callable_default_id": "test_abcde",
281300
},
282301
},
@@ -290,6 +309,7 @@ def test_dumpdata(self):
290309
"null_id_with_no_default": None,
291310
"not_null_id_but_blank": "",
292311
"no_index_id": self.instance_b.no_index_id,
312+
"unique_id": self.instance_b.unique_id,
293313
"prefixed_and_non_callable_default_id": "test_abcde",
294314
},
295315
},

0 commit comments

Comments
 (0)