【问题标题】:Django: Best way to render model instances based on authorizationDjango:基于授权渲染模型实例的最佳方式
【发布时间】:2022-01-25 20:11:43
【问题描述】:

我想向您询问有关如何解决我现在正在苦苦挣扎的问题的建议。我的目标是有一个简单的页面,一个接一个地呈现我的模型实例,但根据用户,它应该跳过某些实例。

models.py

class Item(models.Model):
        creator= models.ForeignKey(User,null=True, on_delete=SET_NULL)
        title = models.CharField(max_length=200)
        private = models.BooleanField(null=False, blank=True, default=False)

views.py

def topics(request):
    items=Item.objects.all()
    context={'items' : items}
    return render(request, 'items.html', context)

ma​​in.html

    {% for item in items %}
    <div>    
    <p>{{item.title}}</p>
    </div>
    {% endfor %}

问题: 如果“私人”为真,如果用户不是员工,我想跳过该项目。这样我可以根据这个布尔值分离项目。推荐/最好的方法是什么? 我不想要 html 中的 if/else 语句,然后重复代码。随着项目的发展,它变得一团糟。

提前致谢!

一种可能的解决方案:

@Eugenij 的回答给了我过滤views.py 的想法。我只是在 if 语句中检查授权并基于此返回一个查询集。 我的意思是它工作正常,但由于我是 Django 新手,我仍然会感谢其他输入。

views.py

def topics(request):

if request.user.is_staff == True:
        items=Item.objects.all()
else:
        items=Item.objects.filter(private=False)
        
context={'items' : items}
return render(request, 'items.html', context)

【问题讨论】:

    标签: django django-templates


    【解决方案1】:

    我不确定,基于函数的视图有一些常见的方法。

    DRF 中,您可以创建自定义Filter 并将其包含到您的ViewSets 中,如下所示

    
    class BaseKeyFilter(BaseFilterBackend):
        def filter_queryset(self, request, queryset, view):
            if not request.user.is_staff:
                queryset = queryset.filter(private=False)
            return queryset
                
    class ItemViewSet(ModelViewSet):
        queryset = Item.objects.all()
        serialiser = ItemSerializer
        filter_backends = [BaseKeyFilter]
    

    通过您的方法,您可以像这样工作

    def filter_private(request, queryset):
        if not request.user.is_staff:
            queryset = queryset.filter(private=False)
        return queryset
    

    并像这样使用它

    def topics(request):
        items=Item.objects.all()
        items=filter_private(request, items)
        context={'items' : items}
        return render(request, 'items.html', context)
    

    【讨论】:

    • 非常感谢您的快速回答,我对 DRF 不熟悉,所以我现在更喜欢上面写的纯 django 方式。
    • @danbrae 您可以在我的示例中使用def filter_private(request, queryset):def topics(request):,而无需DRF。因此,您可以从视图中消除 if 语句。
    猜你喜欢
    • 2023-02-11
    • 2011-03-26
    • 2019-09-09
    • 2019-03-24
    • 1970-01-01
    • 2012-01-10
    • 2022-08-04
    • 2012-08-29
    • 2011-01-05
    相关资源
    最近更新 更多