0

I'm trying to change the content of a field with my own function. I'm using a simplified function that adds commas between each word. I want to be able to send my comma-fied sentence to the frontend but I don't know how to do that with the serializer that was given in Django documentation. I can't find any examples online of someone trying to do this online. I also need to do this in the backend because some of my other custom functions need access to a specific python library.

Here is my api > views.py

@api_view(['PUT'])
def accentLine(request, pk):
    data = request.data
    line = Lines.objects.get(id=pk)

    if data['accent'] == 'shatner':
        shatnerLine = line.content.replace(' ', ', ')
        line.translation = shatnerLine
        line.save()

    serializer = LineSerializer(instance=line, data=data)

    if serializer.is_valid():
        serializer.save()

    return Response(serializer.data)

Here is my api > models.py

class Lines(models.Model):
    # userId = models.ForeignKey(Users, on_delete=models.CASCADE)
    script = models.ForeignKey(Scripts, null=True, on_delete=models.SET_NULL)
    title = models.CharField(max_length=50, null=True)
    content = models.TextField(max_length=5000, null=True)
    accent = models.CharField(max_length=50, default='english')
    translation = models.TextField(max_length=5000, null=True)
    updatedAt = models.DateField(auto_now=True)

Here is my api > serializers.py

from rest_framework.serializers import ModelSerializer
from .models import Lines

class LineSerializer(ModelSerializer):
    class Meta:
        model = Lines
        fields = '__all__'
thePunctuator
  • 13
  • 1
  • 3
  • Now you're saving the sentence with commas, right? And response contains that data. What else do you want? – Metalgear May 31 '22 at 03:41
  • @DavidLu Thank you for responding! Yeah the line gets saved with commas but when I look at `serializer` it, does not have these changes. I'm guessing because `instance=line` still represents the sentence without commas. Is there a syntax other than `LineSerializer(instance=line, data=data)` where I can get the sentence with commas? Or am I missing some other line of code? In my other functions I'm using a python library to convert the sentence to the international phonetic alphabet (ex. yes => ‘jɛs’) – thePunctuator Jun 01 '22 at 00:46
  • Now comma is added only when `data['accent']` is `shatner`, right? – Metalgear Jun 01 '22 at 02:57
  • @DavidLu Yep a comma is added no problem, it's just not saving in the second portion when I am validating with the serializer. For instance I can add `line = Lines.objects.get(id=pk)` outside/after the if statement, then if I look at `line.translation` there are commas. I've tried assigning it again as something else like `updatedLine = Lines.objects.get(id=pk)` and then using `LineSerializer(instance=updatedLine, data=data)` but this doesn't work. The only other thing I can think of is making two different routes or just not validating with the serializer and creating my own to_dict() method – thePunctuator Jun 01 '22 at 13:25
  • I think you don't have to replace " " to ", " but just show in the frontend with commas. What do you think? – Metalgear Jun 01 '22 at 14:28
  • @DavidLu I could add commas in the frontend with Javascript but my ultimate goal is to use a python library (and it's only available in python, not javascript) to change the sentence with a method I create using this python library. I just used this shatner case to try and find out how to change, save, and send back my changed sentence. Currently, I can't find any examples in the django documentation of people doing that though – thePunctuator Jun 01 '22 at 16:07

1 Answers1

1

First and foremost, you are calling save on the model instance twice by calling it directly on the instance, and then again on the serializer. The serializer save method will perform save on the model instance itself. Docs on saving instances with serializers: https://www.django-rest-framework.org/api-guide/serializers/#saving-instances

To achieve what you want to do you should create a custom serializer field probably called TranslationField and either override the to_internal_value method to perform your string mutations before the data is persisted to the database, or override to_representation which will perform the string mutations before the data is returned from the serializer. It depends on if you wish to persist the field... with commas or add the commas when getting the data via serializer. Docs on custom fields here: https://www.django-rest-framework.org/api-guide/fields/#custom-fields

Once you set up your custom field you will not perform any mutations in your accentLine view and instead simply pass the request data to the serializer like so

@api_view(['PUT'])
def accentLine(request, pk):
    data = request.data
    line = Lines.objects.get(id=pk)

    serializer = LineSerializer(instance=line, data=data)

    if serializer.is_valid():
        serializer.save()

    return Response(serializer.data)
chakos
  • 26
  • 2