Python Django - 模型内的函数。如何从视图中调用它?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21093591/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 22:03:08  来源:igfitidea点击:

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

pythondjangodjango-models

提问by André

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.

我正在 Django 中设计一个模型,但我不知道这是否是最好的方法。我有一个名为“History”的模型,在这个模型中,我有一个专门的函数来处理这个模型的插入。

Alternative 1

备选方案 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.

要将数据插入到 History 模型中,我将始终必须使用“insert_history”函数。

My questions here are:

我的问题是:

The code above is correct?

上面的代码正确吗?

If yes, how can I call the "insert_history" from a view?

如果是,我如何从视图中调用“insert_history”?



Alternative 2

备选方案 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?

正确的做法是什么?如果备选方案 1 是正确的,我如何从视图中调用“insert_history”?

Best Regards,

此致,

采纳答案by skoll

Does insert_history use self? Or does it create a new History object?

insert_history 使用 self 吗?或者它是否创建了一个新的 History 对象?

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

顺便说一句,创建新对象的方法的常规名称是create. 另外,看看https://docs.djangoproject.com/en/1.9/ref/models/instances/#creating-objects

回答by sirfilip

I think that it is most appropriate to use custom manager https://docs.djangoproject.com/en/dev/topics/db/managers/for this problems.

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

回答by Steinar Lima

Just select your History instance (eg. with primary key 1):

只需选择您的历史实例(例如,主键为 1):

hist = History.objects.get(pk=1)

...and call your method using the histvariable:

...并使用hist变量调用您的方法:

hist.insert_history(...)

回答by Burhan Khalid

To insert data to the History model I will always have to use the insert_historyfunction.

Yes, it will set the field3, a datetime, based on some logic that I will write inside insert_history

要将数据插入到 History 模型中,我将始终必须使用该insert_history函数。

是的,它会根据我将在里面写的一些逻辑设置 field3,一个日期时间 insert_history

The easiest way is to override the savemethod:

最简单的方法是覆盖该save方法

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.

现在,无论何时保存方法 -field3的值都将是自定义保存方法中计算的结果。您无需修改​​视图中的任何内容即可使其正常工作。

回答by NKortesmaa

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.

只是为了扩展@burhankhalid 的回答,因为我由于相当高的代表要求而无法发表评论,我在保存我的模型时也有类似的需要更改另一个模型,但是 Burhan Khalid 提出的解决方案帮助我开始。

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

我的提议假设 Request 将有一个“attrib1”,并且它会尝试从 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

因此,重写 save() 方法和修改(和保存)其他对象的整个概念也有所不同