Получение идентификатора вместо имени в списке

Я делаю CRUD проект с внешними ключами и использую сериализаторы. Я хочу получить название категории, подкатегории, цвета и размера вместо их идентификаторов. модели следующие:

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>

ниже приведена функция вставки

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})

вместо названия категорий подкатегорий цвета размера и т.д. я получаю id Ниже показано, как product_insert выглядит на веб-странице enter image description here

где здесь проблема?

Вы должны указать в сериализаторе, что вы хотите, чтобы внешние ключи отображались в виде строк:

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__"

Это отображает все, что возвращается методом __str__ объекта, который вы можете переопределить, чтобы вернуть его имя.

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

Альтернатива

Если вы не хотите трогать ваш сериализатор (StringRelatedField доступен только для чтения, что может означать, что некоторые операции вы не сможете выполнить, например POST), вы всегда можете добавить дополнительные параметры к вашим сериализованным данным, сделав что-то вроде этого:

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})

Тогда вы можете просто использовать category_display_name, color_display_name, size_display_name и sub_category_display_name для отображения вашей таблицы в шаблоне (конечно, вам нужно определить методы __str__ моделей Categories, Colors, Size и SUBCategories здесь же). Однако это может привести к проблемам с производительностью при работе с большими базами данных, поэтому не очень рекомендуется...

Вернуться на верх