@YuriyCherniy

Как избавиться от дублирования кода?

Возникла необходимость расширить контекстные данные в паре классов. Переопределил метод get_context_data, в результате чего получил два одинаковых метода в разных классах. Посоветуйте какой подход использовать в данном случае для соблюдения принципа DRY?

class ItemListView(ListView):
    model = Item
    paginate_by = 9

    def get_context_data(self, **kwargs):
        '''
        Add phone number to context data
        '''
        user = User.objects.get(pk=1)
        data = super().get_context_data(**kwargs)
        try:
            data['phone_number'] = user.userprofile.phone_number
        finally:
            return data


class ItemDetailView(DetailView):
    model = Item

    def get_context_data(self, **kwargs):
        '''
        Add phone number to context data
        '''
        user = User.objects.get(pk=1)
        data = super().get_context_data(**kwargs)
        try:
            data['phone_number'] = user.userprofile.phone_number
        finally:
            return data
  • Вопрос задан
  • 288 просмотров
Решения вопроса 1
@antonksa
from django.views.generic import View, ListView, DetailView


class AddUserPhoneToContextMixin(View):
    def get_context_data(self, **kwargs):
        '''
        Add phone number to context data
        '''
        ctx = super().get_context_data(**kwargs)
        try:
            user = User.objects.get(pk=1)
            ctx['phone_number'] = user.userprofile.phone_number
        finally:
            return ctx


class ItemListView(AddUserPhoneToContextMixin, ListView):
    model = Item
    paginate_by = 9


class ItemDetailView(AddUserPhoneToContextMixin, DetailView):
    model = Item


Только не очень понятно почему только pk=1, что будет если его нет, и почему в try-except вы обернули попытку доступа к userprofile. Еще считается, что except без указания конкретных классов обрабатываемых исключений это bad practice. В таком случае вы теряете контроль над пониманием, какое конкретно исключение произошло - то ли коннект в базе оборвался, то ли юзер не существует, то ли поля такого нет у его профиля.

Хорошая практика - это указывать конкретно что бы обрабатываете:
try:
    phone_number = user.userprofile.phonenumber
except UserProfile.DoesNotExists:
    raise NotFound('Warning! User profile did not created!')
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы