Django:隐藏主键(pk)并使用带有get_queryset的DetailView

时间:2013-04-25 11:46:43

标签: django django-class-based-views

关注此主题:django: How do I hash a URL from the database object's primary key?,我想隐藏用户的主键并在我的urlconf中使用Detailview。我能够在大多数情况下使用按位XOR完成此隐藏(它在我的视图函数中工作),直到我到达必须“取消屏蔽”在url中发送到我的子类的掩码主键的部分。 DetailView

如何在发送给我的DetailViewFilteredOnUser(DetailView)实例之前“取消屏蔽”我的pk_masked命名组?有没有办法在urlconf中将mask_toggle(pk_unmasked)发送到我对DetailViewFilteredOnUser的调用?在搜索解决方案时,我在Django文档中找到了关于pk_url_kward的内容,但我无法使其工作,反正我认为这不能帮助我对DetailView操作的主键执行操作。

这是我的掩蔽功能:

def mask_toggle(number_to_mask_or_unmask):
    return int(number_to_mask_or_unmask) ^ settings.MASKING_KEY

我的模型是包含“项目”的“pkgs”:

class Pkg(models.Model):
    user = models.ForeignKey(User, editable=False)
    tracking_number = models.CharField(max_length=60, unique=True)

class Item(models.Model):
    pkg = models.ForeignKey(Pkg)
    description = models.CharField(max_length=300)

以下是我的urls.py中的内容:

class ListViewFilteredOnUser(ListView):
    def get_queryset(self):
        return Pkg.objects.order_by('-created_at').filter(user=self.request.user)

class DetailViewFilteredOnUser(DetailView):
    def get_queryset(self):
    qs = super(DetailViewFilteredOnUser, self).get_queryset()
        return qs.filter(user=self.request.user)

....

url(r'^(?P<pk_masked>\d+)/$',
    login_required(DetailViewFilteredOnUser.as_view( model=Pkg,
                        template_name='pkgs/detail.html'
                        )), 
    name='detail'),

所以问题是如果我的urlconf中的命名组是“pk”,那么一个被屏蔽的主键(因为屏蔽键是url中的内容)被发送到DetailView。如果我的urlconf中的命名组是“pk_masked”,那么我需要在某处做pk=mask_toggle(pk_masked),我无法弄清楚在哪里或如何做到这一点。感谢。

1 个答案:

答案 0 :(得分:1)

如果我正确理解了您的问题,您需要覆盖get_object(这会使get_queryset几乎无关紧要,但您仍然可以使用它来清晰起见)。类似的东西:

class DetailViewFilteredOnUser(DetailView):
    model = Pkg
    template_name = 'pkgs/detail.html'
    def get_queryset(self):
        return super(DetailViewFilteredOnUser, self).get_queryset().filter(user=self.request.user)
    def get_object(self):
        return self.get_queryset().get(pk=mask_toggle(self.kwargs.get("pk_masked"))

(当然,不要忘记捕捉异常,为了清晰和简洁,我将其留下了。)