Smart One-To-One Field
For Django
django-smartonetoonefield provides utility fields discussed in this Fusionbox blog post
Compatibility
- Python: >= 3.12
- Django: >= 4.2
Installation
-
Install the latest version:
pip install django-smartonetoonefield
poetry add django-smartonetoonefield
-
Add
smartonetoonefieldtoINSTALLED_APPSin your project'ssettings.py.
Usage
AutoOneToOneField
If you can create a related model by just filling in one field, then AutoOneToOneField will simplify your code.
To use, define an AutoOneToOneField field on a model with a relation to another field. This will ensure that the related model object will always exist, even if it must be created upon first access.
models.py:
class CustomerProfile(models.Model):
user = AutoOneToOneField('User', related_name='customer_profile')
user = User.objects.all()[0]
user.customer_profile # Always returns a customer profile
SoftOneToOneField
If you cannot create the related model by simply setting the foreign key on the related model, then a SoftOneToOneField might work better for you.
With SoftOneToOneField, if the related model object exists, the lookup will work as normal. But if the related model object does not exist, then the attribute will be None.
models.py:
class CustomerProfile(models.Model):
user = SoftOneToOneField('User', related_name='customer_profile')
views.py:
class MyProfileView(DetailView):
def get_context_data(self, **kwargs):
kwargs = super(MyProfileView, self).get_context_data(**kwargs)
# This will not raise an exception if the customer_profile does
# not exist
kwargs.update(my_profile=self.customer_profile)
return kwargs
AddFlagOneToOneField
Sometimes, when you need to check if a related model exists or not, it can be unwieldy to query the relation directly. A workaround to this is to define properties on the reverse related model:
models.py:
class User(AbstractUser):
# ...
def is_customer(self):
return hasattr(self, 'customer_profile')
class CustomerProfile(models.Model):
user = models.OneToOneField('User', related_name='customer_profile')
However, this can necessitate creating a custom default user model for a project, and this can be impossible if you need to override a model in a third party Django app.
Instead of overriding models or querying the related fields directly, the AddFlagOneToOneField will automatically add flags to the related model to make it easier to query related fields:
models.py:
class CustomerProfile(models.Model):
user = AddFlagOneToOneField('auth.User', related_name='customer_profile',
flag_name='is_customer')
class MerchantProfile(models.Model):
user = AddFlagOneToOneField('auth.User', related_name='merchant_profile',
flag_name='is_merchant')
class EmployeeProfile(models.Model):
user = AddFlagOneToOneField('auth.User', related_name='employee_profile',
flag_name='is_employee')
views.py:
user = User.objects.get(email='customer@example.com')
user.is_customer # True
user.is_merchant # False
user.is_employee # False
Since the AddFlagOneToOneField won't throw exceptions on access, you don't have to override, inherit, or modify other models when using the specified flags.
TODO
I have intentionally kept this app very small to minimize the maintenance burden. But contributions are very welcome!
License
BSD
Release files for django-smartonetoonefield 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| django_smartonetoonefield-0.1.2.tar.gz | 3.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| django_smartonetoonefield-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 7.0 kB
Release files / django_smartonetoonefield-0.1.2.tar.gz
| Download URL | django_smartonetoonefield-0.1.2.tar.gz |
|---|---|
| Size | 3.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e6ec16dea42f1e98147179774d332812b392fb821271de6e779d40aa6b430019
|
|
BLAKE2b-256 checksum How to use checksums |
b129f92be5fe827140ac817bd98433301761701c36c78363c873635c006cfc16
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.12.9
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 28, 2025.
Transparency logRelease files / django_smartonetoonefield-0.1.2-py3-none-any.whl
| Download URL | django_smartonetoonefield-0.1.2-py3-none-any.whl |
|---|---|
| Size | 3.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5d85f9d050a32613271531f70f824a6de00a12340b9ec251301e616170d4a458
|
|
BLAKE2b-256 checksum How to use checksums |
7bc0b1ef51d61e1c409f03dd1568cc1144a9a805f313e57b0c6c801317ebaca6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.12.9
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 28, 2025.
Transparency log