0

I want to generate a table on my template, showing some data that I get from a method declared on my Task class

models.py

class Task(models.Model):
...
def check_if_finished(self):
    resp = requests.get(
     'http://my.rest.api/tasks/view/{}'.format(self.task_id))
    resp_data = resp.json()
    resp_finished = resp_data['task']['started_on']
    if resp_finished is None:
        return False
    else:
        return resp_finished

I know that there is no sense in calling a method on template, but what do I need to use to show this data?

template.html

{{ task.is_finished(task.task_id) }}

2 Answers2

1

When you write a model method you pass on self as parameter, which obviously refers to instance itself. Change your model method to something like this

class Task(models.Model):
    fields
    def is_finished(self):
        return appropriate boolean from here

Now in your template you can use this simply as {{ task.is_finished }}. Notice that I am not passing any id as a parameter. This is because, when writing a model method you pass self as parameter which refers to instance on which method is being called.

I hope this makes sense to you and helps you understand model methods in a simple way.

Rajesh Yogeshwar
  • 2,111
  • 2
  • 18
  • 37
0

I don't fully understand your question, why can't you just sent in task_id as a parameter?

class Task(models.Model):
...
def check_if_finished(self, task_id):
    resp = requests.get(
     'http://my.rest.api/tasks/view/{}'.format(task_id))
    resp_data = resp.json()
    resp_finished = resp_data['task']['started_on']
    if resp_finished is None:
        return False
    else:
        return resp_finished

then call it anytime:

{{ task.check_if_finished(task.task_id) }}

Could also make task_id an optional parameter.

def check_if_finished(self, task_id=None):
    task_id = task_id or self.task_id   
    resp = requests.get...

I'm not sure why you wouldn't want to use the task_id on the instance though. If you never will then maybe it should be a static method?

@staticmethod
def check_if_finished(cls, task_id): 
    ...

I don't think Django models prevent any of these options. Hopefully something there was helpful, else I need a bit more information and what you are trying to accomplish.

Edit: Django templates don't allow calling function/methods with arguments. You need to create a custom template tag or just call the function in the view and send the result to the template. See previous question.

Community
  • 1
  • 1
General Kandalaft
  • 2,215
  • 2
  • 18
  • 25
  • When i Try that I Get this error message: > Could not parse the remainder: '(task.task_id)' from 'task.check_if_finished(task.task_id)' – Fillipe Feitosa Jul 25 '16 at 02:51
  • Oh that's a template error. I just looked it up and it seems you can't call functions/method with arguments in Django templates. You need to either create a custom template tag (https://docs.djangoproject.com/en/dev/howto/custom-template-tags/#howto-custom-template-tags) or do that check in the view and send the correct value into the template. – General Kandalaft Jul 25 '16 at 02:58
  • For my `Task.objects.all()` I want to check if the task is done, via an API request. Then I want to show in a table if this task is done or not. – Fillipe Feitosa Jul 25 '16 at 02:59
  • I would prefer to do this chack on the view, but I have no Idea how to do it. ` """List with all user tasks.""" tasks_from_user = Task.objects.all().filter(user=request.user) return render_to_response( 'vix/list.html', RequestContext(request, { 'request': request, 'tasks_from_user': tasks_from_user })) ` – Fillipe Feitosa Jul 25 '16 at 03:01
  • I would say the easiest thing is to make the API request, check if it is finished, then send that value into the template such as `is_finished` and then do `{{is_finished}}` or wrap an if with that. – General Kandalaft Jul 25 '16 at 03:02
  • @FillipeFeitosa add it to the request context. `return render_to_response( 'vix/list.html', RequestContext(request, { 'request': request, 'tasks_from_user': tasks_from_user, 'is_finished': task.check_if_finished(task.task_id) }))` – General Kandalaft Jul 25 '16 at 03:03
  • But how one shall pass the task_id to a `is_finished = check_if_finished(?)` ? – Fillipe Feitosa Jul 25 '16 at 03:05
  • Ah I get what you're saying, you're sending in a list and for each one you're checking if it is finished. Why can't you use self.task_id in the method call? Each task object can check for itself. – General Kandalaft Jul 25 '16 at 03:07
  • how and where would I do that? – Fillipe Feitosa Jul 25 '16 at 03:12
  • It seem that this solved the problem: > #model.py > is_finished = check_if_finished If I do not use the `()`, the method gets the instanciated object. Thx for your help. – Fillipe Feitosa Jul 25 '16 at 03:16
  • You already had that set up in your question. Just change `{{ task.is_finished(task.task_id) }}` to {{ task.check_if_finished }} assuming that calls the function (try it) else make a property `is_finished` on the task object (by adding the `@property` decorator to the function, normally you would also save the result on the instance self._is_finished = .., return self._is_finished). – General Kandalaft Jul 25 '16 at 03:17