Got AttributeError when attempting to get a value for field '' on serializer ''

Viewed 6008

I would like to be able to see the customers accounts. As you can see Accounts has foreign key to Customer. The idea is to be able to see the customer info with nested accounts objects, but it gives me a error

Got AttributeError when attempting to get a value for field `accounts_items` on serializer `CustomerSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `Customer` instance.
Original exception text was: 'Customer' object has no attribute 'Account'.

so like this example where songs in the the artist object:

enter image description here

####MODELS####
class Account(models.Model):
    amount = models.FloatField(null=True)
    name = models.CharField(max_length=40)
    account_type = models.CharField(max_length=11, choices = ACCOUNT_TYPES)
    customer_id = models.ForeignKey(Customer, on_delete = models.CASCADE, default = None)
    bank_id = models.ForeignKey(Bank, on_delete = models.CASCADE, default = None)

    def __str__(self):
        return '{} {} {} {} {}'.format(self.amount, self.name, self.account_type, self.customer_id, self.bank_id)


class Customer(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    first_name = models.CharField(max_length=20)
    last_name = models.CharField(max_length=40)
    phone = models.CharField(max_length=40)
    email = models.EmailField(max_length = 100)
    rank = models.CharField(max_length=11, choices = RANK_TYPES)
    bank_id = models.ForeignKey(Bank, on_delete = models.CASCADE, default = None)

    def __str__(self):
        return '{} {} {} {} {} {} {}'.format(self.id, self.first_name, self.last_name, self.phone, self.email, self.rank, self.bank_id)

###VIEW###
class customer_page(generics.RetrieveUpdateDestroyAPIView):
    queryset = Customer.objects.all()
    serializer_class = CustomerSerializer

###SERIALIZER###
class AccountSerializer (serializers.ModelSerializer):

    class Meta:
        fields = ('id', 'amount', 'name', 'account_type', 'customer_id', 'bank_id')
        model = Account


class CustomerSerializer (serializers.ModelSerializer):
    accounts_items = AccountSerializer(source='Account')

    class Meta:
        fields = ('id', 'user', 'first_name', 'last_name', 'phone', 'email', 'rank', 'bank_id', 'accounts_items')
        model = Customer

2 Answers

You need to change your serializers to this:

 
    class AccountSerializer (serializers.ModelSerializer):
    
        class Meta:
            fields = ('id', 'amount', 'name', 'account_type', 'customer_id', 'bank_id')
            model = Account
    
    
    class CustomerSerializer (serializers.ModelSerializer):
        accounts_items = serializers.SerializerMethodField()
    
        class Meta:
            fields = ('id', 'user', 'first_name', 'last_name', 'phone', 'email', 'rank', 'bank_id', 'accounts_items')
            model = Customer
    
        def get_accounts_items(self, obj):
            customer_account_query = models.Account.objects.filter(
                customer_id=obj.id)
            serializer = AccountSerializer(customer_account_query, many=True)
    
            return serializer.data

This should work

You can also use this method:

###SERIALIZER###
class AccountSerializer(serializers.ModelSerializer):

   class Meta:
        fields = ('id', 'amount', 'name', 'account_type', 'customer_id', 'bank_id')
        model = Account


class CustomerSerializer(serializers.ModelSerializer):
   accounts_items = AccountSerializer()

   class Meta:
       fields = ('id', 'user', 'first_name', 'last_name', 'phone', 'email', 'rank', 'bank_id', 'accounts_items')
       model = Customer

and For ManyToManyField you need to pass many=True

Here is an Example:

accounts_items = AccountSerializer(many=True)
Related