Automatically delete an object from the database if one attribute of the object is TRUE.
I've tried Django Signals, but it didn't help.
class Question(models.Model):
name = models.CharField(max_length=50)
email = models.EmailField(max_length=50)
question = models.TextField(max_length=200)
answered = models.BooleanField(default=False)
def __str__(self):
return self.name
If I change the "answered" field to TRUE in Admin Panel, then this object must be automatically deleted from the database.
You will need post_save signals by using something like:
from .models import Question
from django.db.models.signals import post_save
from django.dispatch import receiver
#receiver(post_save, sender=Question)
def save_profile(sender, instance, **kwargs):
if instance.answered:
instance.delete()
Related
I'm starting to learn Django and have a class called Customer in my models.
class Customer(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE,
primary_key=True)
cart = models.ManyToManyField(Product)
orders = models.ManyToManyField(Order)
def __init__(self, user):
self.user = user
I'm importing django.contrib.auth to register users to the database, but I would like to also initialize a Customer object upon registration.
I first attempted to override the save() method from the UserCreationForm and initialize a Customer object there:
class UserCreationForm(forms.ModelForm):
def save(self, commit=True):
user = super(UserCreationForm, self).save(commit=False)
user.set_password(self.cleaned_data["password1"])
customer = Customer(user)
customer.save()
if commit:
user.save()
return user
But it did not seem to create a Customer object.
Alternatively, is it better to extend the User class to have the Customer class fields? I initially thought I should keep authentication separate, which is why I created the Customer class.
Might be better if you created a signal instead!
from django.db.models import signals
from django.dispatch import receiver
from django.contrib.auth.models import User
from path.to.models import Customer
#receiver(signals.post_save, sender = User)
def create_customer(sender, instance, created, *args, **kwargs):
if created:
c = Customer(...) #create your customer object
c.save()
and in apps.py, import signals to run it.
I'm trying to save a User and a Profile in django which are linked together using a oneToOneField but I'm getting an error saying
duplicate key value violates unique constraint
"auth_user_username_key
eventhough I dont have any duplicates.
I also get this error:
duplicate key value violates unique constraint
"api_profile_user_id_key" DETAIL: Key (user_id)=(9) already exists.
Here is my code:
model.py
from django.db import models
from django.contrib.auth.models import User
from django.db.models import CharField, OneToOneField
from django.db.models.signals import post_save
from django.dispatch import receiver
class Profile(models.Model):
user = OneToOneField(User, on_delete=models.CASCADE)
phone_number = CharField(max_length=20)
account_type = CharField(max_length=10, default='basic')
facebook_id = CharField(max_length=20, blank=True)
google_id = CharField(max_length=20, blank=True)
notification_id = CharField(max_length=40, blank=True)
# TODO add account info and watchlist
def __str__(self):
return self.user.email
#receiver(post_save, sender=User)
def user_save(sender, instance, **kwargs):
Profile.objects.create(user=instance)
view.py:
#api_view(['POST'])
def sign_up(request):
data = request.data
user = User.objects.create_user(username=data['username'],
password=data['password'],
first_name=data['first_name'],
last_name=data['last_name'],
email=data['email']
)
user.profile.phone_number = data['phone_number']
user.save()
return Response('hey')
I think the problem is in the post_save receiver however I'm not sure.
create_user is also calling save(), then you also call user.save(), the post_save signal is being called twice for one user, you get the error because two Profile objects are being created for one user
You could do:
#receiver(post_save, sender=User)
def user_save(sender, instance, **kwargs):
Profile.objects.get_or_create(user=instance)
This is my Django Models.py
class Test1(models.Model):
id = models.AutoField(db_column='Id', primary_key=True)
name = models.TextField(db_column='Name', blank=True, null=True)
class Test2(models.Model):
id = models.AutoField(db_column='Id', primary_key=True)
sequence = models.IntegerField(db_column='Sequence')
test1id = models.ForeignKey('Test1', models.DO_NOTHING,null=False, db_column='Test1Id')
what i am trying to do is to ensure when the Test1 id is saved, it automatically fills in the test1id.
Not sure what you want to do here, but if you want to implement any post save actions for model look at django signals. Particularly at post_save signal.
Here is example usage of post_save signal, for model Test1(suppose you want to create new Test2 object):
from django.db.models.signals import post_save
from django.dispatch import receiver
#receiver(post_save, sender=Test1)
def create_test2(sender, instance, created, **kwargs):
Test2.objects.create(test1id=instance)
You can redefine the save method:
def save(self, **kwargs):
if self.pk is None:
super(Test1, self).save()
Test2.objects.create(test1id=self)
else:
super(Test1, self).save()
So when you save Test1, a Test2 entry is created
I would like to run some code specifically when the is_active field is changed for a Django User, similar to how the save method works for other models:
class Foo(models.Model):
...
def save(self, *args, **kwargs):
if self.pk is not None:
orig = Foo.objects.get(pk=self.pk)
if orig.is_active != self.is_active:
# code goes here
Can this be done through another model that is in one to one relation with the User model? Something like:
class Bar(models.Model):
owner = models.OneToOneField(User, on_save=?)
...
I guess I could duplicate the is_active field on the related model and then set the is_active field on the User when saving the related model. But this seems like a bit of a messy solution.
You're looking for this Signal
from django.db.models.signals import pre_save
from django.contrib.auth.models import User
def do_your_thing(sender, instance, **kwargs):
# Do something
print(instance)
pre_save.connect(do_your_thing, sender=User)
Here's my models.py:
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
class Userprofile(models.Model):
user = models.OneToOneField(User, primary_key=True)
username = user.__unicode__()
path = './data/'+username+'/'
file = models.FileField(upload_to=path)
labelfile = models.FileField(upload_to=path, blank=True)
def __unicode__(self):
return u"%s" % self.user.username
def create_user_profile(sender, instance, created, **kwargs):
if created:
Userprofile.objects.create(user=instance)
post_save.connect(create_user_profile, sender=User)
the problem is:
AttributeError: 'OneToOneField' object has no attribute 'model'
I want a file upload function that it can save in a index related to the User's name, but I can't find a good way to do it. And I hope someone can help me. Thanks.