Ошибка типа: неподдерживаемые типы операндов для +: 'NoneType' и 'NoneType - PullRequest
0 голосов
/ 01 апреля 2019

Я новый пользователь в Python, у меня проблема с типом None, я посмотрел другой вопрос, но проблема сохраняется.

Мой код ищет пятницу и субботу между двумя датами, пока это работает, но когда я суммирую обе, у меня появляется эта ошибка:

"TypeError: неподдерживаемые типы операндов для +: 'NoneType' и 'NoneType'

После того, как я верну результат в функцию.

Вот мой код:

    # -*- coding: utf-8 -*-

import datetime
import calendar
calendar.setfirstweekday(calendar.SUNDAY)

from odoo import models, fields, api

class HrMission(models.Model):
    _name = "hr.employee.mission"
    _description = "hr mission"
    _inherit = "hr.employee.mission"

    days_compensation =fields.Float(compute='get_compensation', compstring='Jours de récupération', help="Jours de récupération si la mission contient les jours de repos",
                             required=True, readonly=True,)

    @api.multi
    @api.depends('mission_start_date', 'mission_end_date')
    def get_compensation(self):
        for rec in self:
            if rec.mission_start_date and rec.mission_end_date:
                time1 = datetime.datetime.strptime(rec.mission_start_date, "%Y-%m-%d")
                time2 = datetime.datetime.strptime(rec.mission_end_date, "%Y-%m-%d")
                week = {}
                leave_value = {}
        # Compute Number Of Friday And Saturday
                for i in range((time2 - time1).days):
                    day = calendar.day_name[(time1 + datetime.timedelta(days=i+1)).weekday()]
                    week[day] = week[day] + 1 if day in week else 1                    
                fri = week.get('Friday')  # Result Number 4 Of Friday If "Start Date", "End date" --> "01/01/2017", "31/01/2017"
                sat = week.get('Saturday') # Same thing that friday
                friandsat = mon + sat # Error ---> "TypeError: unsupported operand type(s) for +: 'NoneType' and 'NoneType'"
                rec.days_compensation = friandsat

Ответы [ 2 ]

0 голосов
/ 01 апреля 2019
  • Следует помнить, что даты начала и окончания оба должны быть включены в диапазон дат.Например, если обе даты datetime.datetime(2019, 3, 1), то должен ли быть ответ 1?
...
def get_compensation(self):
    def date_range_inclusive(rec):
        # if either date is undefined, then so is date range
        if not rec.mission_end_date or not rec.mission_start_date:
            return iter([])

        # Add 1 for inclusivity of both start and end dates
        num_days = abs((rec.mission_end_date - rec.mission_start_date).days) + 1
        return (rec.mission_start_date + timedelta(days=n) for n in range(num_days))

    for rec in self:
        # date range, including both start and end dates
        dates = date_range_inclusive(rec)
        # desired days to count
        day_selection = (calendar.FRIDAY, calendar.SATURDAY)

        rec.days_compensation = sum([dt.weekday() in day_selection for dt in dates])

Приведенный выше код будет предполагать, что диапазон дат включительно.Удалите + 1, чтобы сделать его не включенным.В поле days_compensation будет установлено значение 0, если не включены ни пятницы, ни субботы.

  • Обратите внимание, что нет необходимости преобразовывать данные между типами данных, поскольку оба календарных дня перечисляютсяи weekday функция в datetime вычисляет целые числа, которые можно сравнивать.

  • Другая вещь, о которой следует помнить, в соответствии с https://www.odoo.com/documentation/8.0/reference/orm.html

computed fields are not stored by default, they are computed and returned when requested. Setting store=True will store them in the database and automatically enable searching

Следовательно, вы можете захотеть:

days_compensation = fields.Float(compute='get_compensation', compstring='Jours de récupération', help="Jours de récupération si la mission contient les jours de repos", required=True, readonly=True,
store=True)

Обратите внимание, что единственным обновлением было store=True

0 голосов
/ 01 апреля 2019

Я играл с вашим кодом. Кажется, это своего рода работа. Он выясняет, какие дни недели существуют в диапазоне дат. Проблема, с которой вы сталкиваетесь, возникает в том случае, если в вашем диапазоне дат нет ни пятницы, ни субботы (обратите внимание, что у вас есть переменная с именем mon, которая задается при поиске ключа пятница).

Так что, похоже, ваша проблема в том, что вы должны учесть случай, когда у вас нет обоих дней недели в диапазоне дат, который вы предоставляете в качестве входных данных. В этом случае либо неделя, либо неделя ('пятница') и неделя ('суббота') не будут существовать на вашей карте week , поэтому mon и / или sat будет None , и у вас возникнет проблема.

Чтобы ваш код работал, я добавил его ниже:

class Rec:
    def __init__(self, start, end):
        self.mission_start_date = start
        self.mission_end_date = end

self = [
    Rec("2019-3-31", "2019-4-1")
]

get_compensation(self)

Это позволяет мне заставить ваш код обрабатывать пару дат. Если диапазон дат, которые я здесь указываю, включает в себя как пятницу, так и субботу, ваш код работает нормально. В противном случае это точно та ошибка, о которой вы говорите.

Если вы измените строки:

mon = week.get('Friday')
sat = week.get('Saturday')

до:

mon = week.get('Friday') if 'Friday' in week else 0
sat = week.get('Saturday') if 'Saturday' in week else 0

тогда ваш код не падает ни для каких диапазонов дат, с которыми я его тестировал. Я не знаю, вычисляет ли он результаты, которые вы хотите, потому что вы не держитесь за результаты своих вычислений и не возвращаете их.

...