axenaxii
axenaxii

Reputation: 18

Django Rest Framework Hiding the JSON data

I have just started learning Django Rest Framework. I want to hide the api that is visible when we go to its url so that no one can see any data whenever they enter that url. I just need the url to post data (for ex- from a membership form...name email and stuff). How can I achieve this. Most of the questions here only talk about hiding browsable api for which they use JSONRenderer but I want to remove the JSON completely. Please do tell if I am thinking in the wrong direction. The idea behind this is that I don't want the information I ask from a user to be visible to everyone through that url. I tried achieving this in the following way. Is this a fine way of doing this or is this going to mess up the application, because I don't see any errors and the post requests are working. I am using React for the frontend. This is my first time posting a question. Please tell if you need any other information. Thanks a lot in advance.

I have only done this in the first if block {if request.method == 'GET':}, I returned a string instead of serializer.data and now whenever i go to membershipform/ it just shows "serializer.data" instead of all the objects.

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

Also I want to create a membership id which follows a format of year membership_type and id(pk) (for ex: 2021B000001) so I implemented it in the POST method if block. Is this a correct way of doing this or is there any other way? Thanks a lot for your help. Any suggestions would be helpful as I am still learning Django and feel like I am just brute forcing through stuff.

EDIT: This is the updated models.py and 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)

This is the response I'm getting when I do a post request, response after post request

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

The membership_id is 2021S00None , here None is supposed to be the id(pk).

Upvotes: 0

Views: 661

Answers (1)

Roman Mkrtchian
Roman Mkrtchian

Reputation: 2996

If you don't need to access the Memberform list but only to create a Memberform for that view, you can remove the 'GET' from the supported methods of your view:

@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
        # [...]

Regarding your membership_id field built from the date, id and type fields, what you did will probably work, but if you don't need that behavior only for this specific view but always for your model, you can do it at the model level instead, by overriding predefined save() model method. This way you will not have to repeat that field creation for other views creating a Memberform object.

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()

Upvotes: 0

Related Questions