52
get_or_create() is just a convenience function so there’s nothing wrong with writing your own, like pavid has shown or
result = Model.objects.filter(field__lookup=value)[0]
if not result:
result = Model.objects.create(...)
return result
EDIT
As suggested, changed the [:1] slice (which returns a single-entry list) after the filter to [0] (which returns the actual object). The problem with this is it will raise an exception if there is not match to the query.
This will also raise a simliar exception:
Model.objects.filter(field_lookup=value).latest()
Looking at the question again, I’m not sure whether the original poster is looking to return multiple objects/rows, or just a way to get around raising an exception when retrieving a single object/row.
Here’s another option?
results = Model.objects.filter(...)
if results.exists():
return results
else:
return Model.objects.create(...)
and another:
result = None
try:
result = Model.objects.get(...)
except Model.DoesNotExist:
result = Model.objects.create(...)
There’s nothing wrong with raising & catching exceptions!
37
From django 1.6 there is a convenience method first() that returns the first result in a filter query, or None.
obj = Model.manager.filter(params).first()
if obj is None:
obj = Model.objects.create(params)
- [Django]-How to set current user to user field in Django Rest Framework?
- [Django]-Unable log in to the django admin page with a valid username and password
- [Django]-Disable Django South when running unit tests?
11
Here’s a manager method that will allow you to extend this function elegantly
class FilterOrCreateManager(models.Manager):
"""Adds filter_or_create method to objects
"""
def filter_or_create(self, **kwargs):
try:
created = False
obj = self.filter(**kwargs).first()
if obj is None:
obj = self.create(**kwargs)
created = True
return (obj,created)
except Exception as e:
print(e)
Then ensure you add the manager to whichever model(s) you want to use this on:
class MyObj(models.Model):
objects = FilterOrCreateManager()
After that, you will be able to use it as you would get_or_create
:
obj_instance, created = MyObj.filter_or_create(somearg='some value')
- [Django]-Django Unit Testing taking a very long time to create test database
- [Django]-Django: How to check if the user left all fields blank (or to initial values)?
- [Django]-PIL /JPEG Library: "decoder jpeg not available"
7
I just came across this question and wanted to contribute because no one has suggested actually catching the IndexError.
try:
obj = Model.objects.filter(params)[0]
except IndexError:
obj = Model.objects.create(params)
- [Django]-How do I modify the session in the Django test framework
- [Django]-Django: order_by multiple fields
- [Django]-How to cache Django Rest Framework API calls?
4
Do it in one line:
obj = Model.objects.filter(params).first() or Model.objects.create(params)
- [Django]-Manipulating Data in Django's Admin Panel on Save
- [Django]-Django rest framework: query parameters in detail_route
- [Django]-Django admin – make all fields readonly
1
You can try this:
result = Model.objects.filter(field__lookup=value)[0]
if not result:
result = Model.objects.create(...)
return result
- [Django]-What's the difference between select_related and prefetch_related in Django ORM?
- [Django]-Using Basic HTTP access authentication in Django testing framework
- [Django]-How can I retrieve a list of field for all objects in Django?
0
This works for me:
In your view, call something like this:
obj = Category.objects.get_or_create_category(form.cleaned_data.get('name'))
In your Model manager, create a function like this:
class CategoryManager(models.Manager):
def get_or_create_category(self, query):
try:
result = Category.objects.filter(name = query)[0]
except:
result = Category.objects.create(name = query)
return result
The logic is simple. First, try to retrieve the first Category object who’s name matches the query string (which is provided by the form). If the retrieval fails (because it doesn’t exist), create a new Category with the string as its name. Return the result for use in your view.
- [Django]-How do you know if memcached is doing anything?
- [Django]-Unit Testing a Django Form with a FileField
- [Django]-Django model constraint for related objects