Передайте идентификатор объекта QuerySet в модель, чтобы получить себя - PullRequest
0 голосов
/ 21 марта 2019

Я пытаюсь вызвать метод в моих моделях для запуска, нажав URL-адрес. Когда он попадает, он возвращает и выдает сообщение об ошибке «неподдерживаемые типы операндов для -: 'datetime.datetime' и 'NoneType'".


views.py

from django.shortcuts import render
from rest_framework import viewsets
from .serializers import EntrySerializer
from .models import Entry

class EntryView(viewsets.ModelViewSet):
  serializer_class = EntrySerializer
  queryset = Entry.objects.all()

entryId = Entry.objects.filter(end_time__isnull=True).values('id')
# returns <QuerySet [{'id': 8}]>
for id in entryId:
    entryIdNum = id['id']
    #returns 8 
entry = Entry()

def ToggleView(request):
  entry.toggle_paused()
  entry.save()

models.py

from django.db import models
from django.db.models import F, ExpressionWrapper, fields
from django.utils import timezone
from dateutil.relativedelta import relativedelta
from decimal import Decimal

class Entry(models.Model):
  start_time = models.DateTimeField()
  end_time = models.DateTimeField(blank=True, null=True, db_index=True)
  seconds_paused = models.PositiveIntegerField(default=0)
  pause_time = models.DateTimeField(blank=True, null=True)
  comments = models.TextField(blank=True)
  date_updated = models.DateTimeField(auto_now=True)
  hours = models.DecimalField(max_digits=11, decimal_places=5, default=0)

def _str_(self):
    return self.TUID

@property
def total_hours(self):
    """
    Determined the total number of hours worked in this entry
    """
    total = self.get_total_seconds() / 3600.0

    # in case seconds paused are greater than the elapsed time
    if total < 0:
        total = 0
    return total

@property
def is_paused(self):
    """
    Determine whether or not this entry is paused
    """
    return bool(self.pause_time)

def pause(self):
    """
    If this entry is not paused, pause it.
    """
    print('Pause Hit')

    if not self.is_paused:
        self.pause_time = timezone.now()

def pause_all(self):
    """
    Pause all open entries
    """
    entries = self.user.timepiece_entries.filter(end_time__isnull=True)
    for entry in entries:
        entry.pause()
        entry.save()

def unpause(self, date=None):
    print('Unpause Hit')
    if self.is_paused:
        if not date:
            date = timezone.now()
        delta = date - self.pause_time
        self.seconds_paused += delta.seconds
        self.pause_time = None

def toggle_paused(self):
    """
    Toggle the paused state of this entry.  If the entry is already paused,
    it will be unpaused; if it is not paused, it will be paused.
    """
    print('Toggle Pause Hit')
    if self.is_paused:
        self.unpause()
    else:
        self.pause()


def check_overlap(self, entry_b, **kwargs):
    """Return True if the two entries overlap."""
    consider_pause = kwargs.get('pause', True)
    entry_a = self
    # if entries are open, consider them to be closed right now
    if not entry_a.end_time or not entry_b.end_time:
        return False
    # Check the two entries against each other
    start_inside = entry_a.start_time > entry_b.start_time \
        and entry_a.start_time < entry_b.end_time
    end_inside = entry_a.end_time > entry_b.start_time \
        and entry_a.end_time < entry_b.end_time
    a_is_inside = entry_a.start_time > entry_b.start_time \
        and entry_a.end_time < entry_b.end_time
    b_is_inside = entry_a.start_time < entry_b.start_time \
        and entry_a.end_time > entry_b.end_time
    overlap = start_inside or end_inside or a_is_inside or b_is_inside
    if not consider_pause:
        return overlap
    else:
        if overlap:
            max_end = max(entry_a.end_time, entry_b.end_time)
            min_start = min(entry_a.start_time, entry_b.start_time)
            diff = max_end - min_start
            diff = diff.seconds + diff.days * 86400
            total = entry_a.get_total_seconds() + entry_b.get_total_seconds() - 1
            if total >= diff:
                return True
        return False

def is_overlapping(self):
    if self.start_time and self.end_time:
        entries = self.user.timepiece_entries.filter(
            Q(end_time__range=(self.start_time, self.end_time)) |
            Q(start_time__range=(self.start_time, self.end_time)) |
            Q(start_time__lte=self.start_time, end_time__gte=self.end_time)
        )

        totals = entries.aggregate(max=Max('end_time'), min=Min('start_time'))

        totals['total'] = 0
        for entry in entries:
            totals['total'] = totals['total'] + entry.get_total_seconds()

        totals['diff'] = totals['max'] - totals['min']
        totals['diff'] = totals['diff'].seconds + \
            totals['diff'].days * 86400

        if totals['total'] > totals['diff']:
            return True
        else:
            return False
    else:
        return None

def save(self, *args, **kwargs):
    self.hours = Decimal('%.5f' % round(self.total_hours, 5))
    super(Entry, self).save(*args, **kwargs)

def get_total_seconds(self):
    """
    Determines the total number of seconds between the starting and
    ending times of this entry. If the entry is paused, the end_time is
    assumed to be the pause time. If the entry is active but not paused,
    the end_time is assumed to be now.
    """
    start = self.start_time
    end = self.end_time
    if not end:
        if self.is_paused:
            end = self.pause_time
            print(end)
            print('------------------')
        else:
            end = timezone.now()
    delta = end - start
    if self.is_paused:
        # get_paused_seconds() takes elapsed time into account, which we do not want
        # in this case, so subtract seconds_paused instead to account for previous pauses
        seconds = delta.seconds - self.seconds_paused
    else:
        seconds = delta.seconds - self.get_paused_seconds()
    return seconds + (delta.days * 86400)

Я знаю, что ошибка исходит из метода get_total_seconds (). Когда вызывается self.start_time, он возвращает объект Entry (None). Как я могу передать entryIdNum или entryId из представлений в модель, чтобы она знала, что такое self?

...