简体   繁体   中英

Django - Function inside a model. How to call it from a view?

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,

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

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.

我认为最适合使用自定义管理器https://docs.djangoproject.com/en/dev/topics/db/managers/来解决这个问题。

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(...)

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM