Delete Objects after Saving - Django - python

I have a problem about Delete Object after savings Django
I have model Like:
class Reaction(models.Model):
REACT_TYPES = (
(LIKE, 'Like'),
(LOVE, 'Love'),
)
user = models.ForeignKey(User)
react_type = models.CharField(max_length=100, choices=REACT_TYPES, default='LIKE')
How can I write a save():
When saving, it should remove the available object with THE SAME user and react_type or create one if object doesn't exists.
def save(self, force_insert=False, force_update=False, *args, **kwargs):
user = Reaction.objects.filter(user=self.user)
react_type = Reaction.objects.filter(user=self.react_type)
# Model delete if exist
if self.id.exists() & self.react_type.exists() :
self.Reaction.delete()
# Model create if not exist
else :
self.Reaction.create()
Fix with #dirkgroten solution:
class ReactionManager(models.Manager):
def save(self, force_insert=False, force_update=False, *args, **kwargs):
similars = Reaction.objects.filter(user=self.user, react_type=self.react_type)
if similars.exists():
print ('exist')
similars.delete()
else:
print ('Not exist')
similars.create()
super(Reaction, self).save(*args, **kwargs)

Please check this code. It may help you:
def save(self, force_insert=False, force_update=False, *args, **kwargs):
similars, created = Reaction.objects.get_or_create(user=self.user, react_type=self.react_type)
if not created:
print ('exist')
similars.delete()
super(Reaction, self).save(*args, **kwargs)

This code will work ok.
def save(self, force_insert=False, force_update=False, *args, **kwargs):
similars = Reaction.objects.filter(user=self.user, content_type=self.content_type, object_id=self.object_id)
if similars.exists():
similars.delete()
similars.update(user=self.user, react_type=self.react_type)
else :
similars.update(user=self.user, react_type=self.react_type)
super(Reaction, self).save(*args, **kwargs)

Related

override save and clean method in django

hello i have StoreCheckout model and i override save and clean method but conditions in override methods not work.
class StoreCheckout(models.Model):
store = models.ForeignKey(
to=Store,
on_delete=models.CASCADE,
limit_choices_to={
'is_confirm': True
},
)
pay_date = models.DateTimeField()
amount = models.PositiveBigIntegerField()
bank_number = models.PositiveBigIntegerField(validators=[bank_number_validate])
def __str__(self):
return self.store.name
def save(self, *args, **kwargs):
if not self.bank_number:
self.bank_number = self.store.bank_number
if not self.pay_date:
self.pay_date = datetime.now()
super(StoreCheckout, self).save(*args, **kwargs)
def clean(self, *args, **kwargs):
if not settings.MIN_CHECKOUT <= self.store.wallet <= settings.MAX_CHECKOUT:
raise ValidationError(
f'amount of your store must between {settings.MIN_CHECKOUT} and {settings.MAX_CHECKOUT} toman'
)
super(StoreCheckout, self).save(*args, **kwargs)

django application with postgresql error value too long for type character varying(1)

I have a problem with django app and POSTGRESQL database with the slug field.
Error:
value too long for type character varying(1)
I test my app with sqlite database and everything works fine, but my app does not work in postgresql database. Any ideas why this is the case?
Test 1:
class MyModel(models.Model):
name = models.CharField(max_length=254)
slug_name = models.SlugField(max_length=254)
def save(self, *args, **kwargs):
self.slug_name = slugify(self.name)
super(MyModel, self).save(*args, **kwargs)
Test 2:
class MyModel(models.Model):
name = models.TextField(max_length=500)
slug_name = models.SlugField(max_length=500)
def save(self, *args, **kwargs):
self.slug_name = slugify(self.name)
super(MyModel, self).save(*args, **kwargs)
Test 3:
class MyModel(models.Model):
name = models.TextField()
slug_name = models.SlugField()
def save(self, *args, **kwargs):
self.slug_name = slugify(self.name)
super(MyModel, self).save(*args, **kwargs)
You're trying to insert a value with more that one character into a field specified as character varying(1). SQLite3 will allow this (see https://sqlite.org/datatype3.html) but PostgreSQL will give an error - i.e., it enforces that you have specified the maximum length as 1.

How to check in models save() method if ManyToManyField is empty?

I have model with field rules = models.ManyToManyField(blank=True, null=True) and aggregation = models.BooleanField(default=False).
And I want to make aggregation=False in case if rules is empty. In other words, if there are no any rule entered or already stored in database, aggregation field should be always == False.
def save(self, *args, **kwargs):
if not self.rules:
self.aggregation = False
super(MyModel, self).save(*args, **kwargs)
Is this what you mean?
Edit: I see that you might want to check the database also. No problem:
def save(self, *args, **kwargs):
models = MyModel.objects.filter(rules__isnull=False).exists()
if not self.rules and not models:
self.aggregation = False
super(MyModel, self).save(*args, **kwargs)

Python/Django Iterate ManyToMany Related Fields

I need some help with an issue.
I have three models, Reference, Relation ans Circuit. Relation is an inline of the first one. Circuit and Relation are related. What I have to do is:
- I'm in Reference 1 and I have selected some Circuits inside my Relation1 to RelationN.
- When I save, I need to save Relation1 to RelationN, and other RelationFirst (created when the Reference model is saved) who must contain all the Circuits that exist in the other Relations of that Reference.
The code that I have right now, who doesn't do it, is:
class Reference(models.Model):
title = models.CharField(max_length=200, verbose_name = _('title'))
def __unicode__(self):
return u"\n %s" %(self.title)
def save(self, force_insert=False, force_update=False, *args, **kwargs):
is_new = self.id is None
super(Reference, self).save(force_insert, force_update, *args, **kwargs)
if is_new:
Relation.objects.create(reference=self, first = True)
relation = Relation.objects.get(reference=self, first = True)
circuit = Circuit.objects.get(name = '0')
relation.circuit.add(circuit)
class Relation(models.Model):
first = models.BooleanField()
reference = models.ForeignKey(Reference)
circuit = models.ManyToManyField('Circuit', verbose_name = _('Circuits'), null=True, blank=True, related_name = 'relation_circuit')
def __unicode__(self):
return u"%s" %(self.reference)
def save(self, force_insert=False, force_update=False, *args, **kwargs):
relation1 = Relation.objects.get(reference=self.reference, first = True)
super(Relation, self).save(force_insert, force_update, *args, **kwargs)
for circ in self.circuits:
circuit = Circuit.objects.get(pk = circ)
relation1.circuit.add(circuit)
Any help? Because I can't iterate the ManyToManyRelatedField, and I don't know how to do it. Thank you very much!
You should do it that way:
for circ in self.circuit.all():

How to change input fields while overriding a django save() method

Suppose I had this following code:
class MyModel(models.Model):
...
...
def save(self, *args, **kwargs):
# pre-save edits can go here...
super(MyModel, self).save(*args, **kwargs)
When I create and save a model, MyModel(blah, blah, blah), there is a possibility that
one of the input fields is "None". In the overridden save method, the goal is to check for if a field is none, and if one is, change it to some other default value.
Are the input fields in args or kwargs? And is overriding save() even the proper way to do this?
I was thinking something like this:
def save(self, *args, **kwargs):
if 'username' in args and args['username'] is None:
args['username'] = some_default_value
super(MyModel, self).save(*args, **kwargs)
So where are the input params? args* or **kwargs, thank you.
I think it's better a pre_save signal to see if a input value is None:
from django.db import models
from django.db.models.signals import pre_save
from django.dispatch import receiver
class MyModel(models.Model):
field1 = models.TextField()
field2 = models.IntegerField()
#receiver(pre_save, sender=MyModel)
def mymodel_save_handler(sender, instance, *args, **kwargs):
if instance.field1 is None or instance.field1 == "":
instance.field1 = default_value
If you prefer override save method you can access to the model fields with self
def save(self, *args, **kwargs):
if self.username is None:
self.username = some_default_value
super(MyModel, self).save(*args, **kwargs)

Categories