37π
I like this approach:
if request.method == 'POST':
form = MyForm(request.POST)
if form.is_valid():
book, created = Book.objects.get_or_create(**form.cleaned_data)
That way you get to take advantage of all the functionality of model forms (except .save()) and the get_or_create shortcut.
1π
You just need two cases in the view before the postback has occurred, something like
if id:
form = MyForm(instance=obj)
else
form = MyForm()
then you can call form.save() in the postback and Django will take care of the rest.
- [Django]-What is a Django QuerySet?
- [Django]-How can I render a ManyToManyField as checkboxes?
- [Django]-How to make Django QuerySet bulk delete() more efficient
1π
What do you mean by βif an identical record existsβ? If this is a simple ID check, then your view code would look something like this:
if request.method == 'POST':
form = MyForm(request.POST)
if form.is_valid():
form.save()
else:
if get_id:
obj = MyModel.objects.get(id=get_id)
form = MyForm(instance=obj)
else:
form = MyForm()
The concept here is the check occurs on the GET request, such that on the POST to save, Django will already have determined if this is a new or existing record.
If your check for an identical record is more complex, it might require shifting the logic around a bit.
- [Django]-ValueError: Missing staticfiles manifest entry for 'favicon.ico'
- [Django]-Using subdomains in django
- [Django]-Django: Display current locale in a template
0π
I would do this β
if request.method == 'POST':
form = MyForm(request.POST)
if form.is_valid():
name = form.cleaned_data['name']
author = form.cleaned_data['author']
price = form.cleaned_data['prince']
if name and author and price:
book, created = Book.objects.get_or_create(name=name, \
author=author, price=price)
if created:
# fresh entry in db.
else:
# already there, maybe update?
book.save()
- [Django]-How to run django unit-tests on production database?
- [Django]-Django Class Based View for both Create and Update
- [Django]-Django admin and MongoDB, possible at all?
0π
Based on the answers and comments, I had to create a different solution for my case, which included the use of unique_together on the base model. You may find this code useful as well, as I actually made it fairly generic.
I have custom code in the form.save()
method that I want to utilize for creating a new object, so I donβt want to simply not use the form.save()
call. I do have to put my code check in the form.save()
method, which I think is a reasonable place to put it.
I have a utility function to flatten iterables.
def flatten(l, a=list()):
"""
Flattens a list. Just do flatten(l).
Disregard the a since it is used in recursive calls.
"""
for i in l:
if isinstance(i, Iterable):
flatten_layout(i, a)
else:
a.append(i)
return a
In the ModelForm
, I overwrite the validate_unique()
method:
def validate_unique(self):
pass
This is about what my save method looks like:
def save(self, commit=True):
unique_fields = flatten(MyObject._meta.unique_together)
unique_cleaned_data = {k: v for k, v in self.cleaned_data.items() if k in unique_fields}
# check if the object exists in the database based on unique data
try:
my_object = MyObject.objects.get(**unique_cleaned_data)
except MyObject.DoesNotExist:
my_object = super(MyModelFormAjax, self).save(commit)
# -- insert extra code for saving a new object here ---
else:
for data, value in self.cleaned_data.items():
if data not in unique_fields:
# only update the field if it has data; otherwise, retain
# the old value; you may want to comment or remove this
# next line
if value:
setattr(my_object, data, value)
if commit:
my_object.save()
return my_object
- [Django]-Django β {% csrf_token %} was used in a template, but the context did not provide the value
- [Django]-Django with Pluggable MongoDB Storage troubles
- [Django]-Django auto_now and auto_now_add