models.py
class Customer(models.Model):
name = models.CharField(max_length=16)
description = models.CharField(max_length=32)
Is it possible to have new model using signals .
For example if i save above model it must give me below model.
def create_customer(sender, instance, created, **kwargs):
class Newname(models.Model):
customername = models.CharField(max_length=100)
signals.post_save.connect(receiver=create_customer, sender=Customer)
def create_customer(sender, instance, created, **kwargs):
Newname.objects.create(customername=instance.name)
This creates a Newname object and saves it to the database. The instance in this case would be the Customer object that you just saved.
Related
My Django site has a database model named Status with:
class Status(models.Model):
x = models.ForeignKey(Person, on_delete=models.SET_NULL, null = True)
The Person database model referenced here contains attributes such as name, profile_pic etc.
In forms.py, I have:
class StatusForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(StatusForm, self).__init__(*args, **kwargs)
class Meta:
model = Status
fields = ['x']
Now, when running the site, I get:
I want the name attribute of the Person to be shown in the choices instead of being shown Person object(1), Person object (2).....
How can I make that happen?
From Other model instance methods[Django-doc]
Most notably, to display an object in the Django admin site and as the value inserted into a template when it displays an object
In your Person model use str()[Django-doc] as
class Person(models.Model):
name = models.charField(max_length=100)
.....
def __str__(self):
return self.name
In your Person model just add the str method as following:
class Person(models.Model):
# Your fields here
def __str__(self):
return self.name
That will return the name for every instance in the choicefield.
I have following two models in my models.py.
class Book(models.Model):
book_id = models.AutoField
book_name = models.CharField(max_length=50)
book_author = models.CharField(max_length=50)
book_category = models.CharField(max_length=50)
class Author(models.Model):
author_id = models.AutoField
author_name = models.CharField(max_length=50)
author_description = models.CharField(max_length=500)
I want whenever I add new row in Book table, it automatically do entry in Author table ( Only author_id and author_name, author_description i will add manually ) for every unique author.
How to do it?
You can do it, in some different way.I suggest you you these ways:
Overwrite Save method of Book model. (Using Save method)
Send Signal to Author model for create Author object.
Now, I implement second way:
#receiver(post_save, sender=Book)
def create_author(sender, instance, created, **kwargs):
if created:
author = Author.objects.create(id=your_id,author_name=your_author_name,author_description=your_author_description)
Book.objects.objects.filter(pk=instance.id).update(author=author)
#receiver(post_save, sender=Book)
def save_author(sender, instance, **kwargs):
instance.author.save()
I have django models as follows :
class Type(models.Model):
limit = models.IntegerField()
name = models.CharField(max_length=50)
default = models.BooleanField()
def __str__(self):
return self.name
class Subscription(models.Model):
started = models.DateField()
type = models.OneToOneField(Type)
def __str__(self):
return self.type.name
class Member(models.Model):
user = models.ForeignKey(to=User)
number = models.CharField(max_length=10)
address = models.CharField(max_length=255)
postcode = models.CharField(max_length=10)
city = models.CharField(max_length=100)
active = models.BooleanField()
subscription = models.OneToOneField(Subscription, on_delete=models.CASCADE)
def __str__(self):
return self.name
Thus, member and subscription need to be OneToOneField relation, and subscription and type also OneToOneField relation.
But I want that member gets subscription of type default=true, if he creates a new account.
This is maybe not the question as it should be, but however, I would like to hear advice.
Thanks.
There are generally two options:
Attach some function to Member post_save signal, in function create appropriate instances if it was called with created=True:
from django.db.models.signals import post_save
from django.dispatch.dispatcher import receiver
#receiver(post_save, sender='myapp.Member')
def create_default_subscription(sender, instance, created, raw, using, update_fields):
if created:
<here create your subscription>
Override Member.save() method and create appropriate instances if self.pk is None.
def save(self, *args, **kwargs):
if self.pk is None:
<here create your subscription>
super().save(*args, **kwargs)
In both cases, you need to remember to associate created Subscription with your new Member.
I have two models like
class Reporter(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
email = models.EmailField()
class Article(models.Model):
headline = models.CharField(max_length=100)
pub_date = models.DateField()
reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)
Now for an object of Article lets say
a=Article.objects.filter(id=1)
a=a[0]
I try to change the headline and the email of the author who has written this article so I do
a.heagline = "Saving foreign key does not work"
a.reporter.email = "changed#email.com"
a.save()
This saves the Article object but does not modify the Reporter.
I explicitly have to do
a.reporter.save()
to see the changes to the reporter object. As this is a Many to One relation it should also modify the Foreign key on saving
How can I save the parent Model too by just calling the childs save method
You could override the save method or just create a custom method.
class Article(models.Model):
...
# Overriding save
def save(self, *args, **kwargs):
self.reporter.save()
super(Article, self).save(*args, **kwargs)
# Creating a custom method
def save_related(self):
self.reporter.save()
self.save()
I suggest you create a custom method because it doesn't introduce unexpected behavior in save()
I have two models:
class Object(models.Model):
object = models.CharField()
price = models.DecimalField()
class History(models.Model):
date = models.DateTimeField()
object= models.ForeignKey(Object)
price = models.DecimalField()
When I create a new history entry, I want to copy actual price from Object to History model.
How can I do that? Need I to use specific method in view?
You can use Django's post-save signal:
Create signal receiver:
# models.py
def history_add_price(sender, instance, **kwargs):
if not instance.price and instance.object and instance.object.price:
instance.price = instance.object.price
instance.save()
return True
Register signal:
# models.py
from django.db import models
models.signals.post_save.connect(history_add_price, sender=History, dispatch_uid="add_price_post_save", weak=False)