Skip to content
Advertisement

Getting ID instead of Name in list

I am doing CRUD project with foreign keys and I am using serializers.I want to get the Name of the categories,sub categories,color and size instead of thier IDs serializer:

class POLLSerializer(serializers.ModelSerializer):
    class Meta:
        model = Products
        fields = "__all__"

models are:

class Products(models.Model):
    categories = models.ForeignKey(Categories,on_delete=models.CASCADE)
    sub_categories = models.ForeignKey(SUBCategories,on_delete=models.CASCADE)
    color = models.ForeignKey(Colors,on_delete=models.CASCADE)
    size = models.ForeignKey(Size,on_delete=models.CASCADE)
    # image = models.ImageField(upload_to = 'media/',width_field=None,height_field=None,null=True)
    title = models.CharField(max_length=50)
    price = models.CharField(max_length=10)
    sku_number = models.CharField(max_length=10)
    product_details = models.CharField(max_length=300)
    quantity = models.IntegerField(default=0)
    isactive = models.BooleanField(default=True)

class Categories(models.Model):
    #made changes to category_name for null and blank
    category_name = models.CharField(max_length=20)
    category_description = models.CharField(max_length=20)
    isactive = models.BooleanField(default=True)

class Colors(models.Model):
    color_name = models.CharField(max_length=10)
    color_description = models.CharField(max_length=10)
    isactive = models.BooleanField(default=True)

class Size(models.Model):
    size_name = models.CharField(max_length=10)
    size_description = models.CharField(max_length=20)
    isactive = models.BooleanField(default=True)

class SUBCategories(models.Model):
    category_name = models.ForeignKey(Categories, on_delete=models.CASCADE)
    sub_categories_name = models.CharField(max_length=20)
    sub_categories_description = models.CharField(max_length=20)
    isactive = models.BooleanField(default=True)
<td>Categories</td>
<td>
    <select name="categories" id="">
     {% for c in context %}
        <option value="{{c.id}}">{{c.category_name}}</option>
     {% endfor %}
   </select>
</td>
<td>Sub-Categories</td>
  <td>
   <select name="sub_categories" id="">
    {% for c in sub_context %}
       <option value="{{c.id}}">{{c.sub_categories_name}}</option>
    {% endfor %}
  </select>
</td>
<td>Colors</td>
<td>
   <select name="color" id="">
   {% for c in color_context %}
      <option value="{{c.id}}">{{c.color_name}}</option>
  {% endfor %}
  </select>
</td>
<td>Size</td>
<td>
  <select name="size" id="">
 {% for c in size_context %}
   <option value="{{c.id}}">{{c.size_name}}</option>
 {% endfor %}
 </select>
</td>

below is the insert function

def insert(request):
    data = {}
    if request.method == "POST":
        print('POST',id)
        data['categories'] = request.POST.get('categories')
        data['sub_categories'] = request.POST.get('sub_categories')
        data['color'] = request.POST.get('color')
        data['size'] = request.POST.get('size')
        data['title'] = request.POST.get('title')
        data['price'] = request.POST.get('price')
        data['sku_number'] = request.POST.get('sku_number')
        data['product_details'] = request.POST.get('product_details')
        data['quantity'] = request.POST.get('quantity')

        form = POLLSerializer(data=data)
        print(form)
        if form.is_valid():
            print('form after valid:',form)
            print("error of form:",form.errors)
            form.save()
            
            messages.success(request, "Record Updated Successfully...!:)")
            return redirect("polls:show")
        else:
            print('form not valid')
            print(form.errors)
    if request.method == "GET":
        print('POST',id)
        category_dict = Categories.objects.filter(isactive=True)
        category = CategoriesSerializer(category_dict, many=True)
        sub_category_dict = SUBCategories.objects.filter(isactive=True)
        sub_category = SUBCategoriesSerializer(sub_category_dict,many=True)
        color_dict = Colors.objects.filter(isactive=True)
        color = ColorsSerializer(color_dict,many=True)
        size_dict = Size.objects.filter(isactive=True)
        size = SizeSerializer(size_dict,many=True)
        hm = {"context": category.data,"sub_context":sub_category.data,"color_context":color.data,"size_context":size.data}
        return render(request, "polls/product_insert.html", hm)
 

show function

def show(request):
    showall = Products.objects.filter(isactive=True) 
    print("show all data:",showall)
    serializer = POLLSerializer(showall,many=True)  
   
    return render(request,'polls/product_list.html',{"data":serializer.data})

instead of name of categories subcategories color size etc I am getting id below is how the product_insert looks on webpage enter image description here

where is the problem here?

Advertisement

Answer

You need to specify in the serializer that you want the foreign keys to be displayed as strings:

from rest_framework import serializers

class POLLSerializer(serializers.ModelSerializer):
    categories = serializers.StringRelatedField(many=False)
    sub_categories = serializers.StringRelatedField(many=False)
    color = serializers.StringRelatedField(many=False)
    size = serializers.StringRelatedField(many=False)
    class Meta:
        model = Products
        fields = "__all__"

This displays whatever is returned by the __str__ method of the object, which you can override to return its name.

class Categories(models.Model):
    category_name = models.CharField(max_length=20)
    category_description = models.CharField(max_length=20)
    isactive = models.BooleanField(default=True)

    def __str_(self):
        return self.category_name

class Colors(models.Model):
    color_name = models.CharField(max_length=10)
    color_description = models.CharField(max_length=10)
    isactive = models.BooleanField(default=True)

    def __str_(self):
        return self.color_name

class Size(models.Model):
    size_name = models.CharField(max_length=10)
    size_description = models.CharField(max_length=20)
    isactive = models.BooleanField(default=True)

    def __str_(self):
        return self.size_name

class SUBCategories(models.Model):
    category_name = models.ForeignKey(Categories, on_delete=models.CASCADE)
    sub_categories_name = models.CharField(max_length=20)
    sub_categories_description = models.CharField(max_length=20)
    isactive = models.BooleanField(default=True)

    def __str_(slef):
        return self.category_name

Alternative

If you do not want to touch your serializer (StringRelatedField is read-only, which may mean there are certain operations you cannot do, like POST), you can always add extra parameters to your serialized data by doing something like this:

def show(request):
    showall = Products.objects.filter(isactive=True) 
    print("show all data:",showall)
    serializer = POLLSerializer(showall,many=True)
    
    data = serializer.data
    
    for i in range(len(data)):
        product = Products.objects.filter(id=data[i]['id']).first()
        data[i]['category_display_name'] = product.categories.__str__()
        data[i]['color_display_name'] = product.color.__str__()
        data[i]['size_display_name'] = product.size.__str__()
        data[i]['sub_category_display_name'] = product.sub_categories.__str__()
   
    return render(request,'polls/product_list.html',{"data":data})

Then, you can simply use the category_display_name, color_display_name, size_display_name and sub_category_display_name to render your table in the template (of course, you need to define the __str__ methods of the Categories, Colors, Size and SUBCategories models here too). This may lead to performance issues when working with large databases, though, so not really recommended…

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement