【问题标题】:Django Rest Framework Hiding the JSON dataDjango Rest Framework 隐藏 JSON 数据
【发布时间】:2021-08-03 19:56:45
【问题描述】:

我刚开始学习 Django Rest Framework。我想隐藏当我们转到其 url 时可见的 api,这样当他们输入该 url 时,没有人可以看到任何数据。我只需要 url 来发布数据(例如,来自会员表格......姓名电子邮件和其他东西)。我怎样才能做到这一点。这里的大多数问题只涉及隐藏他们使用 JSONRenderer 的可浏览 api,但我想完全删除 JSON。如果我想错了方向,请务必告诉我。这背后的想法是,我不希望通过该 url 向每个人询问我向用户询问的信息。我尝试通过以下方式实现这一目标。这是这样做的好方法还是会弄乱应用程序,因为我没有看到任何错误并且发布请求正在工作。我在前端使用 React。这是我第一次发布问题。请告诉您是否需要任何其他信息。提前非常感谢。

我只在第一个 if 块 {if request.method == 'GET':} 中完成了此操作,我返回了一个字符串而不是 serializer.data,现在每当我转到 membersform/它只显示“serializer.data”而不是所有对象。

views.py

class CsrfExemptSessionAuthentication(SessionAuthentication):

    def enforce_csrf(self, request):
        return 

@api_view(['GET', 'POST'])
@authentication_classes([CsrfExemptSessionAuthentication, BasicAuthentication])
def memberform_list(request):
    if request.method == 'GET':
        memberform = Memberform.objects.all()
        serializer = MemberformSerializer(memberform, many=True)
        return Response("serializer.data")

    elif request.method == 'POST':
        serializer = MemberformSerializer(data=request.data)

        if serializer.is_valid():
            instance = serializer.save()
            # creating a membershipid
            fid = instance.id
            strid = str(fid)
            temp = '{:>06}'
            if len(strid) <= 6:
                memstrid = temp.format(strid)
            else:
                memstrid = strid
            memyear = str(instance.created_at.year)
            memtype = instance.membership_type[0]
            memid = memyear + memtype + memstrid
            instance.membership_id = memid
            instance.save()

            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


@api_view(['GET', 'PUT', 'DELETE'])
@authentication_classes([CsrfExemptSessionAuthentication, BasicAuthentication])
def memberform_detail(request, pk):
    try:
        memberform = Memberform.objects.get(pk=pk)

    except Memberform.DoesNotExist:
        return Response(status=status.HTTP_404_NOT_FOUND)

    if request.method == 'GET':
        serializer = MemberformSerializer(memberform)
        return Response(serializer.data)

    elif request.method == 'PUT':
        serializer = MemberformSerializer(memberform, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    elif request.method == 'DELETE':
        memberform.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

models.py

class Memberform(models.Model):
    id = models.AutoField(primary_key=True)
    created_at = models.DateTimeField(auto_now_add=True)
    membership_id = models.CharField(max_length=13, null=True)
    name = models.CharField(max_length=500)
    email = models.CharField(max_length=200, unique=True)
    alt_email = models.CharField(max_length=1500)
    designation = models.CharField(max_length=500)
    qualification = models.CharField(max_length=500)
    specialization = models.CharField(max_length=500)
    institute_university = models.CharField(max_length=1000)
    institute_city = models.CharField(max_length=500)
    institute_state = models.CharField(max_length=500)
    institute_pincode = models.CharField(max_length=1000)
    permanent_address = models.CharField(max_length=1000)
    permanent_address_city = models.CharField(max_length=1000)
    permanent_address_state = models.CharField(max_length=1000)
    permanent_address_pincode = models.CharField(max_length=1000)
    mobile = models.CharField(max_length=50)
    official_phone = models.CharField(max_length=50)
    membership_type = models.CharField(max_length=50)
    research_interests = models.CharField(max_length=1500)

    def __str__(self):
        return self.name

我还想创建一个会员 ID,它遵循 year members_type 和 id(pk) 的格式(例如:2021B000001),所以我在 POST 方法 if block 中实现了它。这是这样做的正确方法还是有其他方法?非常感谢你的帮助。任何建议都会有所帮助,因为我仍在学习 Django,并且觉得我只是在蛮力地通过一些东西。

编辑:这是更新的 models.py 和 views.py

models.py

class Memberform(models.Model):
    id = models.AutoField(primary_key=True)
    created_at = models.DateTimeField(default=datetime.datetime.now)
    membership_id = models.CharField(max_length=20, null=True)
    membership_type = models.CharField(max_length=50)
    ....rest of the fields

    def save(self, *args, **kwargs):
        strid = str(self.id)
        if len(strid) <= 6:
            memstrid = '{:>06}'.format(strid)
        else:
            memstrid = strid
        memyear = str(datetime.datetime.now().year)
        memtype = self.membership_type[0] if self.membership_type else ""
        memid = memyear + memtype + memstrid
        self.membership_id = memid
        super().save(*args, **kwargs)

    def __str__(self):
        return self.name

views.py

@api_view(['GET', 'POST'])
@authentication_classes([CsrfExemptSessionAuthentication, BasicAuthentication])
def memberform_list(request):
    if request.method == 'GET':
        memberform = Memberform.objects.all()
        serializer = MemberformSerializer(memberform, many=True)
        return Response(serializer.data)

    elif request.method == 'POST':
        serializer = MemberformSerializer(data=request.data)

        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


@api_view(['GET', 'PUT', 'DELETE'])
@authentication_classes([CsrfExemptSessionAuthentication, BasicAuthentication])
def memberform_detail(request, pk):
    try:
        memberform = Memberform.objects.get(pk=pk)

    except Memberform.DoesNotExist:
        return Response(status=status.HTTP_404_NOT_FOUND)

    if request.method == 'GET':
        serializer = MemberformSerializer(memberform)
        return Response(serializer.data)

    elif request.method == 'PUT':
        serializer = MemberformSerializer(memberform, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    elif request.method == 'DELETE':
        memberform.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

这是我发出帖子请求时得到的响应, 发布请求后回复

created_at: "2021-05-14T02:29:21.105382Z"
id: 31
membership_id: "2021S00None"
membership_type: "Silver"
...rest of the data

membership_id 是 2021S00None ,这里 None 应该是 id(pk)。

【问题讨论】:

    标签: python django api django-rest-framework django-views


    【解决方案1】:

    如果您不需要访问Memberform 列表而只是为该视图创建Memberform,则可以从视图支持的方法中删除'GET'

    @api_view(['POST'])
    @authentication_classes([CsrfExemptSessionAuthentication, BasicAuthentication])
    def memberform_list(request):
        serializer = MemberformSerializer(data=request.data)
    
        if serializer.is_valid():
            instance = serializer.save()
            # creating a membershipid
            # [...]
    

    关于从日期、id 和类型字段构建的 membership_id 字段,您所做的可能会起作用,但如果您不需要仅针对此特定视图但始终针对您的模型的行为,您可以这样做而是在模型级别,由overriding predefined save() model method。这样,您就不必为创建 Memberform 对象的其他视图重复该字段创建。

    class Memberform(models.Model):
        # your fields
    
        def save(self, *args, **kwargs):
            super().save(*args, **kwargs)
            if not self.membership_id:
                strid = str(self.id)
                if len(strid) <= 6:
                    memstrid = '{:>06}'.format(strid)
                else:
                    memstrid = strid
                memyear = str(self.created_at.year)
                memtype = self.membership_type[0] if self.membership_type else ""
                memid = memyear + memtype + memstrid
                self.membership_id = memid
                member_form = Memberform.objects.get(id=self.id)
                member_form.membership_id = self.membership_id
                member_form.save()
    

    【讨论】:

    • 确实,auto_now_add 仅在保存方法后添加当前日期。我已经更新了代码,使其可以调用datetime.datetime.now(),而不是使用created_at 字段的值。这对我来说似乎足够安全,因为您只需要一年。
    • 实际上django.utils.timezone.now() 而不是datetime.datetime.now() 也适合我。
    • 保存方法无效。它给出了一个错误:即使我指定了 null=True,membership_id 也不能为 null。所以,我给了它一个默认值,现在它更新了,但 id 部分总是无。所以我在开始的时候调用了一次self.save(),这样它就可以得到一个pk。现在,membership_id 只是使用默认值保存。我已经更新了我的 models.py。这可能是因为在views.py 中调用了save 方法吗?抱歉删除了我之前的评论,因为我解决了它,然后意识到你已经回答了。
    • 我不确定你的问题。我尝试了一个简单的示例,其中仅包含模型和 save() 覆盖方法,并且它不需要可以为空。它获取包含 id 的构建值。如果您同时在序列化程序级别和模型级别设置值,则必须在其中一个中删除它。
    • 谢谢终于解决了。我没有再次使用save(),而是更新了实例。 Memberform.objects.filter(id=self.id).update(membership_id=memid) 从而避免了无限递归。
    猜你喜欢
    • 1970-01-01
    • 2015-09-15
    • 2016-06-26
    • 2020-03-19
    • 1970-01-01
    • 2018-12-27
    • 1970-01-01
    • 1970-01-01
    • 2012-12-07
    相关资源
    最近更新 更多