django CBV generic DetailView在对象不存在时重定向

django CBV generic DetailView在对象不存在时重定向,django,python-3.x,detailview,Django,Python 3.x,Detailview,我有一个DetailView,如果当前登录的用户创建了userprofile,它将显示userprofile。如果用户没有创建配置文件,我需要一个else条件。因为我是django和python的新手,甚至是CBV的新手,所以我想不出下一步该怎么做。我希望在def get_object()中有一种重定向到UserProfile的方法。 如果不存在userprofile,则会导致相关的Object DoesNotExist错误。如何编写else或except条件以重定向到ProfileView(创

我有一个DetailView,如果当前登录的用户创建了userprofile,它将显示userprofile。如果用户没有创建配置文件,我需要一个else条件。因为我是django和python的新手,甚至是CBV的新手,所以我想不出下一步该怎么做。我希望在def get_object()中有一种重定向到UserProfile的方法。 如果不存在userprofile,则会导致相关的Object DoesNotExist错误。如何编写else或except条件以重定向到ProfileView(创建概要文件的表单)

PS:UserProfile用于创建配置文件,UserProfileView用于查看 已创建配置文件,UserProfileUpdate用于更新现有配置文件

我不想通过url传递PK

我是django 2.0,python 3.6.3

专门寻找如何从DetailView方法重定向Exception/if案例

Models.py

class User(AbstractUser):
    """User model."""

    username = None
    email = models.EmailField(_('email address'), unique=True)
    phone = models.CharField(max_length=128, unique=True, null=True,
                             validators=[validators.RegexValidator(
                                 r'^(?:\+?(\d{2}))?(\d{10})$',
                                 _('Enter a valid phone number. Type without space or special charecter.')
                             )])

    objects = UserManager()

    REQUIRED_FIELDS = ['first_name']
    USERNAME_FIELD = 'email'

    def __str__(self):
        return self.email


class UserProfile(models.Model):
    """User Profile"""
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    country = models.CharField(max_length=128)
    state = models.CharField(max_length=128)
    city = models.CharField(max_length=128)
    landmark = models.CharField(
        max_length=128, help_text='Enter a landmark closest to you')
    address_line_1 = models.CharField(
        max_length=128, help_text='House name/Flat No')
    address_line_2 = models.CharField(
        max_length=128, help_text='Street Name/No')
    address_line_3 = models.CharField(
        max_length=128, help_text='Locality Name')
    pincode = models.IntegerField()
    land_phone = models.CharField(max_length=128, unique=True, null=True,
                                  validators=[validators.RegexValidator(
                                      r'^(?:\+?(\d{4}))\-?(\d{7})$',
                                      _('Enter a valid phone number. Type without space. Format 0400-2012345.')
                                  )])

    def __str__(self):
        return self.user.email
Views.py

class UserProfileFormView(FormView):
    form_class = UserProfileForm
    template_name = 'userprofile.html'
    success_url = '/'

    def form_valid(self, form):
        import pdb
        pdb.set_trace()
        temp_form = form.save(commit=False)
        temp_form.user = self.request.user
        temp_form.save()
        return super().form_valid(form)

    def form_invalid(self, form):
        response = super().form_invalid(form)
        return redirect('users:userprofile')


class UserProfileView(DetailView):
    model = UserProfile
    context_object_name = 'userprofile'
    template_name = 'x.html'

    # def dispatch(self, request, *args, **kwargs):
    #     import pdb; pdb.set_trace()
    #     if self.request.user.userprofile.pk is not None:
    #         pass
    #     else:
    #         return redirect('users:userprofile')

    def get_object(self):
        import pdb; pdb.set_trace()
        self.object = UserProfile.objects.get(pk=self.request.user.userprofile.pk)
        return self.object

    # def get_context_data(self, **kwargs):
    #     import pdb; pdb.set_trace()
    #     context = kwargs
    #     context_object_name = 'userprofile'
    #     context['userprofile'] = UserProfile.objects.get(pk=self.request.user.userprofile.pk)
    #     if context_object_name:            
    #         return context
    #     else:
    #         return redirect('users:userprofile')


class UserProfileUpdate(UpdateView):
    model = UserProfile
    fields = ('address_line_1', 'address_line_2', 'address_line_3',
              'landmark', 'city', 'state', 'country', 'pincode', 'land_phone')

    template_name = 'userprofile.html'
    success_url = 'home'

所以在网上搜索了好几遍之后,这是我能找到的最好的答案。希望其他人会觉得这很有用,或者有更好的知识的人有一个更好的解决方案

class UserProfileView(DetailView):
    model = UserProfile
    context_object_name = 'userprofile'
    template_name = 'x.html'


    def dispatch(self, request, *args, **kwargs):
        try:
            self.object =  self.request.user.userprofile
        except:
            return redirect('users:userprofile')

        self.get_object()
        return super(UserProfileView, self).get(request, *args, **kwargs)

    def get_object(self):        
        self.object = self.request.user.userprofile
        return self.object

我在这里所做的(或者说django为我做的)是使用分派。通过使用dispatch,我能够只过滤那些具有概要文件的用户,以继续获取概要文件或使用get_object方法返回UserProfile对象。如果用户没有配置文件,则dispatch方法中的Exception条件会将用户重定向到配置文件创建页面。如果用户有配置文件,则调度调用(overide.我不确定使用哪个术语)get_object方法来获取现有的对象。总之,get_object方法只能将对象作为响应返回。因此,我尝试重定向的尝试(代码的注释部分)无法工作,因为django不允许这样做。如果我的任何解释是错误的,请指出我的缺点

我知道你的问题很老了,但没有人真正回答过,所以我想我会回答的

我建议在您的用户模型上创建一个方法,用于检查是否存在userprofile,例如:

def has_profile(self):
  return hasattr(self, 'userprofile')
“hasattr”将返回True或False。 现在在调度中,你可以

def dispatch(self, request, *args, **kwargs):
    if not self.request.user.has_profile():
        return redirect('users:userprofile')
    return super().dispatch(request, *args, **kwargs)

我可能错过了几点,1>我不喜欢通过url传递pk,除了部分仍然不起作用。我将发布pdb堆栈跟踪眼睛。确切地在本例中,CreateView=UserProfile。
def dispatch(self, request, *args, **kwargs):
    if not self.request.user.has_profile():
        return redirect('users:userprofile')
    return super().dispatch(request, *args, **kwargs)