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)
If you go into the detail view,
User has no kcal.
error
That's what it says What should I do?
CodePudding user response:
Your code would work if you would have kcal field on User linking your User to Kcal. If you are trying to get object with one to one relation by related name in Django and object does not exist, ObjectDoesNotExist exception is raised. What you should do is embed your redirect in try ... except... block like that:
try:
self.request.user.kcal:
except ObjectDoesNotExist:
return HttpResponseRedirect(reverse('kcalculatorapp:create'))
Of course you could do Kcal.ObjectDoesNotExist but i don't know your project structure if it would not cause circle import error
CodePudding user response:
Firstly, you should override the get
method instead of the dispatch method
and use getattr
to check for a Kcal
relation.
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)
And since you are relying on authentication rather than url kwargs to determine the object to return, you need to override the get_object
method as well.
class KcalDetailView(DetailView):
...
def get_object(self, queryset=None):
return self.request.user.kcal
So your final view should look something like this:
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)