пытается применить принцип DRY к методам моделирования в django - PullRequest
1 голос
/ 05 мая 2020

У меня есть эти два метода, которые идентичны, за исключением имени и одной переменной, и это действительно меня беспокоит, но что бы я ни делал, я не могу понять, как сделать так, чтобы я просто передавал переменную в метод в django. Это два метода, я могу опубликовать модель, если она нужна, но я почти уверен, что вся необходимая информация находится здесь, но для ясности два поля модели - «запуск», «staff_trials» и «опубликовано». все три - просто даты, все остальные переменные создаются в методе:

@property
def progress_launch(self):
    timeline = self.launch - self.published.date()
    current = self.launch - datetime.now().date()
    if timeline < current:
        percentage == 100
    else:
        percentage = 100 - round((current/timeline) * 100)
    min_bar = 1
    max_bar = 100
    if percentage is not None:
        if percentage < min_bar:
             return min_bar
        elif percentage > max_bar:
            return percentage
    else:
        percentage = max_bar
        return percentage

@property
def progress_trials(self):
    timeline = self.staff_trials - self.published.date()
    current = self.staff_trials - datetime.now().date()
    if timeline < current:
        percentage == 100
    else:
        percentage = 100 - round((current/timeline) * 100)
    min_bar = 1
    max_bar = 100
    if percentage is not None:
        if percentage < min_bar:
            return min_bar
        elif percentage > max_bar:
            return percentage
    else:
        percentage = max_bar
        return percentage

Я пытался сделать это:

def progress_launch(self):    
    return percent(trials)

def progress_trials(self):
    return percent(launch)


def percent(_progress)
    timeline = _progress - self.published.date()
    current = _progress - datetime.now().date()
    if timeline < current:
        percentage == 100
    else:
        percentage = 100 - round((current/timeline) * 100)
    min_bar = 1
    max_bar = 100
    if percentage is not None:
        if percentage < min_bar:
            return min_bar
        elif percentage > max_bar:
            return percentage
    else:
        percentage = max_bar
        return percentage

Но, конечно, не сработало. Оба метода работают нормально, это просто ужасно выглядит, и эта конкретная модель сама по себе становится довольно большой. Я понимаю, что это, скорее, проблема OOP (именно поэтому я начал изучать django в первую очередь, чтобы выучить OOP), поскольку, к сожалению, именно здесь я все еще борюсь. Мы будем очень благодарны за любую помощь в улучшении рефакторинга этого кода. Я не могу опубликовать ни одно из сообщений об ошибках, так как их было слишком много, но все они касались переменных, которые не были определены.

1 Ответ

1 голос
/ 05 мая 2020

Просто проверьте, какая модель у вас установлена, используя isinstance, и используйте соответствующее поле:

@property
def progress(self):
    if isinstance(self, LaunchModel):
        start = self.launch
    else:
        start = self.staff_trials
    timeline = start - self.published.date()
    current = start - datetime.now().date()
    # ... etc 

Вы можете сжать это в одну строку:

start = self.launch if isinstance(self, LaunchModel) else self.staff_trials
...