0

I have django api in which i have post model which is linked to comments and categories table by forgin key now i am feching data for post detail and when i try to access category of that post it return s id and i want to access name of category this is my post list view

{
        "id": 4,
        "title": "BLOG PAGE",
        "body": "testing",
        "owner": "ankit",
        "comments": [],
        "categories": [
            2
        ],
        "created_at": "2021-05-07T17:22:32.989706Z"
    },
    {
        "id": 5,
        "title": "Test Post",
        "body": "This is a test Post",
        "owner": "ankit",
        "comments": [],
        "categories": [
            2
        ],

and this is my categories

[
    {
        "id": 2,
        "name": "Python",
        "owner": "ankit",
        "posts": [
            4,
            5,
            6,
            8
        ]
    }
]

and this is my post detail component

export class PostDetail extends React.Component {
  
  constructor(props) {
    super(props);
    const ID = this.props.match.params.id
    this.state = {
      data: [],
      loaded: false,
      placeholder: "Loading"
    };
  }

  formatDate(dateString){
      const options = { year: "numeric", month: "long", day: "numeric" }
      return new Date(dateString).toLocaleDateString(undefined, options)
  }

    componentDidMount() {
    fetch(`${Url}posts/${this.props.match.params.id}`)
      .then(response => {
        if (response.status > 400) {
          return this.setState(() => {
            return { placeholder: "Something went wrong!" };
          });
        }
        return response.json();
      })

      .then(data => {
        this.setState(() => {
          return {
            data,
            loaded: true
          };
        });
      });
  }

  render(){
    return(
      <>
      <h1 className="main-title">{this.state.data.title}</h1>
      <div className="container">
        <div className="box1">
          <h2>Categories</h2>
          <div className="categories">{this.state.data.categories}</div>
        </div>
      </>
      );
  }
}

and i am getting output as 2 when i try to get data like mention above i thought i can access it by putting . in front of categories eg. categories.name but it returns TypeError error

TypeError: Cannot read property 'name' of undefined

this are my serializers

class CategorySerializer(serializers.ModelSerializer):
    owner = serializers.ReadOnlyField(source='owner.username')
    posts = serializers.PrimaryKeyRelatedField(many=True, read_only=True)

    class Meta:
        model = Category
        fields = ['id', 'name', 'owner', 'posts']


class PostSerializer(serializers.ModelSerializer):
    owner = serializers.ReadOnlyField(source='owner.username')
    comments = serializers.PrimaryKeyRelatedField(many=True, read_only=True)

    class Meta:
        model = Post
        fields = ['id', 'title', 'body', 'owner', 'comments', 'categories','created_at']
Ankit Tiwari
  • 4,438
  • 4
  • 14
  • 41

1 Answers1

1

i try to access category of that post it return s id and i want to access name of category this is my post list view

1. For getting only the name of the category.

You can use the SlugRelatedField.

Modify your PostSerializer like so:

class PostSerializer(serializers.ModelSerializer):
    owner = serializers.ReadOnlyField(source='owner.username')
    comments = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
    categories = serializers.SlugRelatedField(many=True, read_only=True, slug_field='name')

    class Meta:
        model = Post
        fields = ['id', 'title', 'body', 'owner', 'comments', 'categories','created_at']

Example JSON response:

{
        "id": 4,
        "title": "BLOG PAGE",
        "body": "testing",
        "owner": "ankit",
        "comments": [],
        "categories": [
            "Python"
        ],
        "created_at": "2021-05-07T17:22:32.989706Z"
    },

2. To nest full Category objects

class PostSerializer(serializers.ModelSerializer):
    owner = serializers.ReadOnlyField(source='owner.username')
    comments = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
    categories = CategorySerializer(many=True)

    class Meta:
        model = Post
        fields = ['id', 'title', 'body', 'owner', 'comments', 'categories','created_at']

Example JSON response:

{
   "id":4,
   "title":"BLOG PAGE",
   "body":"testing",
   "owner":"ankit",
   "comments":[],
   "categories":[
      {
         "id":2,
         "name":"Python",
         "owner":"ankit",
         "posts":[
            4,
            5,
            6,
            8
         ]
      }
   ],
"created_at":"2021-05-07T17:22:32.989706Z"
}
eshaan7
  • 968
  • 2
  • 9
  • 17