React/Django: how to get label of models.TextChoices in React

Viewed 712

I have the following Model in Django:

class Expense(models.Model):

    class ExpenseTypes(models.TextChoices):
        FOOD = 'FOOD', 'Food'
        HOUSE = 'HOUS', 'Home'
        SPORT = 'SPRT', 'Sport and exercices'
        TRANSPORT = 'MOVE', 'Transportation'
        EVERYDAY = 'EVER', 'Everyday Expenses'
        ENTERTAINMENT = 'ENTE', 'Entertainment'
        CLOTHING = 'CLOT', 'Clothes'
        INVESTMENTS = 'INVE', 'Investments'
        EDUCATION = 'EDUC', 'Education'
        SAVING = 'SAVE', 'Saving'
        HOLIDAYS = 'HOLI', 'Holidays'
        DEBT = 'DEBT', 'Debt'
        TAXES = 'TAXS', 'Taxes'

    user = models.ForeignKey(User, on_delete=models.CASCADE)
    title = models.CharField(max_length=32)
    amount = models.DecimalField(max_digits=10, decimal_places=2)
    expense_type = models.CharField(
        max_length=4,
        choices=ExpenseTypes.choices,
        default=ExpenseTypes.FOOD,
    )
    time = models.DateTimeField(default=timezone.now)

with a simple serializer and view:

class ExpenseSerializer(serializers.ModelSerializer):
    class Meta:
        model = Expense
        fields = ('id', 'user', 'title', 'amount', 'expense_type', 'time')

class ExpenseViewSet(viewsets.ModelViewSet):
    queryset = Expense.objects.all()
    serializer_class = ExpenseSerializer
    authentication_classes = (TokenAuthentication, )
    permission_classes = (IsAuthenticated,)

In React when I fetch the Data:

const [expenses, setExpenses] = useState<Expense[]>([]);

  useEffect(() => {
    function formatExpense(expense: any): Expense {
      return {
        id: expense.id,
        title: expense.title,
        amount: expense.amount,
        user: expense.user,
        type: expense.expense_type,
        time: new Date(expense.time),
      };
    }
    async function loadExpenses() {
      try {
        const response = await fetch("http://127.0.0.1:8000/api/Expenses/", {
          method: 'GET',
          headers: {
            'Content-Type': 'application/json',
            'Authorization': 'xxx'
          }
        })
        const Expenses = await response.json()
        setExpenses(Expenses.map((expense: any) => formatExpense(expense)));
      } catch (err) {
        console.log(err);
      };
    }
    loadExpenses();
  }, []) 

I see that for the expense_type I only have the 'keys' (FOOD,HOUS,SPRT,...) without their description. I would like to be able to fetch those description(Food, Home, Sport and exercices, ...) too, this to be able to show those on my frontend. How can this be done?

thanks in advance

1 Answers

I fixed my issue by changing the Serializer to:

class ExpenseSerializer(serializers.ModelSerializer):
    expense_type = serializers.SerializerMethodField()

    class Meta:
        model = Expense
        fields = '__all__'

    def get_expense_type(self, obj):
        return obj.get_expense_type_display()
Related