Nithin
Nithin

Reputation: 5840

Django create object - use default value for None

So I have a Django model which has few non nullable field with default values.

class Article(models.Model):
    id = models.UUIDField(default=uuid4, primary_key=True, editable=False)
    code = models.CharField(max_length=200, default=uuid4, unique=True, null=False)
    company = models.CharField(max_length=200, default=uuid4, unique=True, null=False)

Now i want to do a

Article.objects.get_or_create(company=company, code=am_row['Article code'])

But here the issue is am_row['Article code'] or company can be a None, and in that case i just want a new model to be created using that fields default values.

Currently passing None throws a NOT NULL constraint failed error. How can i achieve this?

So i think this boils down to achieving

Article.objects.create(company=company, code=am_row['Article code'])

Upvotes: 2

Views: 7385

Answers (2)

ruddra
ruddra

Reputation: 51988

You can override the get_or_create method in your model manager, like this:

class CustomManager(models.Manager):
    def get_or_create(self, **kwargs):
        defaults = kwargs.pop('defaults', {})  # popping defaults from values
        for key, value in kwargs.items():
            if value == None:
                kwargs[key] = defaults.get(key)
        return super(CustomManager, self).get_or_create(**kwargs)


class Article(models.Model):
    # ...
    objects = CustomManager()

Then use it in your view like this:

Article.objects.get_or_create(
     company=company,
     code=am_row.get('Article code'),
     defaults={
        'company': uuid.uuid4(),
        'code': uuid.uuid4()
     }
)

If you want the default functionality of get_or_create, then use:

objects = Article._base_manager
objects.get_or_create(...)

Upvotes: 2

gonczor
gonczor

Reputation: 4146

I'd use or operator in this case. Look at the example. If x is None some default value will be passed:

In [1]: import uuid

In [2]: def some_function(something):
   ...:     print(f'Something is {something}')
   ...:

In [3]: x = None

In [4]: some_function(x or uuid.uuid4())
Something is 518d7187-f74d-4620-90de-6104698a7d07

In [5]: x = 'Hello, world!'

In [6]: some_function(x or uuid.uuid4())
Something is Hello, world!

Upvotes: 1

Related Questions