Reputation: 25554
I'm designing a model in Django but I don't know if this is the best way. I have a model called "History" and inside this model I've a specialized function that will handle the inserts to this model.
Alternative 1
class History(models.Model):
field1 = models.ForeignKey(Request)
field2 = models.BooleanField()
field3 = models.DateTimeField()
def __unicode__(self):
return str(self.field1.id)
class Meta: #
ordering = ['-field3']
def insert_history(self):
# Here I will have some business logic to insert the data to the history model
To insert data to the History model I will allways have to use the "insert_history" function.
My questions here are:
The code above is correct?
If yes, how can I call the "insert_history" from a view?
Alternative 2
I've another alternative that I've tested and it works, but does not feel the right way. The code looks like this:
class History(models.Model):
field1 = models.ForeignKey(Request)
field2 = models.BooleanField()
field3 = models.DateTimeField()
def __unicode__(self):
return str(self.field1.id)
class Meta: #
ordering = ['-field3']
def insert_history(field1, field2, field3):
# Here I will have some business logic to insert the data to the history model
And I call it from a view like this:
from app.models import insert_history
insert_history('1', True, 'some_date')
what is the correct way of doing it? If the alternative 1 is correct, how can I call the "insert_history" from a view?
Best Regards,
Upvotes: 18
Views: 34684
Reputation: 11
Just to extend on answer by @burhankhalid, as I were unable to comment due to rather high-ish rep requirement, I had a similar need to alter another model while saving mine, but solution proposed by Burhan Khalid helped me to start.
The model I needed to modify, I had a reference-to from this one
My proposal assumes that Request would have a 'attrib1', and to that it tries to save the value from History.field2
class History(models.Model):
field1 = models.ForeignKey(Request)
field2 = models.BooleanField()
field3 = models.DateTimeField()
def __unicode__(self):
return unicode(self.field1.id) # __unicode__ should return unicode,
# not string.
class Meta: #
ordering = ['-field3']
def save(self, *args, **kwargs):
self.field3 = your calculated value
self.field1.attrib1 = self.field2 # for instance
self.field1.save() # don't forget to save the other
super(History, self).save(*args, **kwargs)
So the whole concept of rewriting the save() method and modifying (and saving) other objects as well made the difference
Upvotes: 1
Reputation: 2452
Does insert_history use self? Or does it create a new History object?
If it creates a new object, I'd do it like this:
class History(models.Model):
@classmethod
def insert_history(cls, field1, field2, field3):
# Here be code
To call it
from app.models import History
History.insert_history(field1, field2, field3)
BTW, the conventional name for a method creating new objects is create
. Also, have a look at https://docs.djangoproject.com/en/1.9/ref/models/instances/#creating-objects
Upvotes: 15
Reputation: 174614
To insert data to the History model I will always have to use the
insert_history
function.Yes, it will set the field3, a datetime, based on some logic that I will write inside
insert_history
The easiest way is to override the save
method:
class History(models.Model):
field1 = models.ForeignKey(Request)
field2 = models.BooleanField()
field3 = models.DateTimeField()
def __unicode__(self):
return unicode(self.field1.id) # __unicode__ should return unicode,
# not string.
class Meta: #
ordering = ['-field3']
def save(self, *args, **kwargs):
self.field3 = your calculated value
super(History, self).save(*args, **kwargs)
Now, whenever you save your method - field3
's value will be whatever is the result of the calculation in your custom save method. You don't need to modify anything in your views for this to work.
Upvotes: 4
Reputation: 7821
Just select your History instance (eg. with primary key 1):
hist = History.objects.get(pk=1)
...and call your method using the hist
variable:
hist.insert_history(...)
Upvotes: 1
Reputation: 1095
I think that it is most appropriate to use custom manager https://docs.djangoproject.com/en/dev/topics/db/managers/ for this problems.
Upvotes: 1