how to get foreignkey names instead of sql reference number django view

Question:

I’m trying to build a simple rest API in Django. I have a transaction, account and stock table. Each transaction points to 1 account and 1 stock(on seperate tables using foreign keys). I’m trying to have my API gets the stock ticker for each transaction and not the sql reference number. Does anyone know how to get simple views to return values instead of table keys?

The serializers I’m using:

class TransactionSerializer(serializers.ModelSerializer):
    class Meta:
        model = Transaction
        fields = "__all__"

class StockSerializer(serializers.ModelSerializer):
    class Meta:
        model = Stock
        fields = "__all__"


class AccountSerializer(serializers.ModelSerializer):
    class Meta:
        model = Account
        fields = "__all__"

The models for transaction and stock:

class Stock(models.Model):
    ticker = models.CharField(max_length=10, unique=True)
    name = models.CharField(max_length=200)
    price = models.FloatField()

    def __str__(self):
        return self.ticker

class Transaction(models.Model):
    account = models.ForeignKey(Account, on_delete=models.CASCADE)
    stock = models.ForeignKey(Stock, on_delete=models.CASCADE)
    amount = models.IntegerField()
    price = models.FloatField()
    type = models.CharField(max_length=10)
    date = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.account

I’m leaving out the account/user model but its a mess and half tied into the django base user model.

The view I’m using is a basic APIView:

class TransactionView(APIView):
    permission_classes = (IsAuthenticated,)
    authentication_classes = (JWTAuthentication,)

    def get(self, request, *args, **kwargs):
        account = Account.objects.get(email=request.user.email)
        transactions = Transaction.objects.filter(account=account)
        serializer = TransactionSerializer(transactions, many=True)
        return Response(serializer.data)

and the output I am getting from postman:

[
    {
        "id": 1,
        "amount": 1,
        "price": 146.1,
        "type": "buy",
        "date": "2022-10-05T04:12:10.414961Z",
        "account": 1,
        "stock": 1
    },
    {
        "id": 2,
        "amount": 1,
        "price": 146.1,
        "type": "buy",
        "date": "2022-10-05T04:17:57.807945Z",
        "account": 1,
        "stock": 1
    }
]

Also the url I am using for the endpoint:

path("transactions/", views.TransactionView.as_view(), name="transactions"),

Sorry for repetition but the basic issue I’m getting is when I call the API endpoint I am getting 1 for stock and 1 for account instead of the stock ticker and account name and I don’t know how to get the view to return all the information without calling a second endpoint that returns the stock and a 3rd endpoint to return the account information.
I was under the impression that the model __str__ function would return information on the object but that isn’t happening here.

Asked By: the-hyphen-user

||

Answers:

You should define a "stock" field and an "account" field in your transaction serializer. (Assigning the relevant serializer as value).
Doing this will allow you to indicate to DRF how to serialize the related model.

class TransactionSerializer(serializers.ModelSerializer):
    stock = StockSerializer()
    account = AccountSerializer()

    class Meta:
       model = Transaction
       fields = "__all__"
Answered By: Alombaros