Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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,

like image 916
André Avatar asked Jan 13 '14 14:01

André


People also ask

How do you call a function from a view?

To call a view function from template with Python Django, we can add a link to the URL of the view function. to add a link to the view with name delete_product in admin_page. html. to add the path to the delete_product view.

What does __ in do in Django?

The keyword after the double underscore ( __ ) in field lookup argument is so called lookup types, there are a lot of built-in lookup types that you can use, of cause you can define custom lookup types when you need, we will tell you how to create custom lookup types in other article.

Can we inherit model in Django?

Models inheritance works the same way as normal Python class inheritance works, the only difference is, whether we want the parent models to have their own table in the database or not. When the parent model tables are not created as tables it just acts as a container for common fields and methods.


2 Answers

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

like image 128
skoll Avatar answered Oct 21 '22 01:10

skoll


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.

like image 41
Burhan Khalid Avatar answered Oct 21 '22 01:10

Burhan Khalid