Django Если нет модели, перенаправьте на createview. Если есть, я бы хотел сделать это в детальном представлении

class KcalDetailView(DetailView):
    model = User
    context_object_name = 'target_kcal'
    template_name = 'kcalculatorapp/detail.html'

    def dispatch(self, request, *args, **kwargs):
        if not self.request.user.kcal:
            return HttpResponseRedirect(reverse('kcalculatorapp:create'))
        return super(KcalDetailView, self).dispatch(request, *args, **kwargs)

model.py

class Kcal(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='kcal', null=True)
    height = models.PositiveIntegerField(default='',  null=False , verbose_name='height')
    weight = models.PositiveIntegerField(default='',  null=False, verbose_name='weight')
    age = models.PositiveIntegerField(default='',  null=False, verbose_name='age')
    created_at = models.DateField(auto_now_add=True, null=True)

Если вы перейдете к детальному представлению,

User has no kcal. ошибка

Вот что там написано. Что мне делать?

введите описание изображения здесь

Ваш код будет работать, если у вас есть поле kcal в User, связывающее вашего пользователя с Kcal. Если вы пытаетесь получить объект с отношением один к одному по связанному имени в Django и объект не существует, то возникает исключение ObjectDoesNotExist. Что вам следует сделать, так это встроить ваш редирект в блок try ... except... следующим образом:

try:
    self.request.user.kcal:
except ObjectDoesNotExist:
    return HttpResponseRedirect(reverse('kcalculatorapp:create'))

Конечно, вы можете сделать Kcal.ObjectDoesNotExist, но я не знаю структуру вашего проекта, не вызовет ли это ошибку импорта круга

Во-первых, вам следует переопределить метод get вместо метода dispatch method и использовать getattr для проверки наличия отношения Kcal.

class KcalDetailView(DetailView):
    ...

    def get(self, request, *args, **kwargs):
        if not getattr(self.request.user, 'kcal', None):
            return HttpResponseRedirect(reverse('kcalculatorapp:create'))
        return super().get(request, *args, **kwargs)

А поскольку вы полагаетесь на аутентификацию, а не на url kwargs для определения возвращаемого объекта, вам нужно переопределить и метод get_object.

class KcalDetailView(DetailView):
    ...

    def get_object(self, queryset=None):
        return self.request.user.kcal

Таким образом, ваш окончательный вид должен выглядеть примерно так:

class KcalDetailView(DetailView):
    context_object_name = 'target_kcal'
    template_name = 'kcalculatorapp/detail.html'

    def get_object(self, queryset=None):
        return self.request.user.kcal

    def get(self, request, *args, **kwargs):
        if not getattr(self.request.user, 'kcal', None):
            return HttpResponseRedirect(reverse('kcalculatorapp:create'))
        return super().get(request, *args, **kwargs)
Вернуться на верх