Получение идентификатора вместо имени в списке
Я делаю 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 выглядит на веб-странице
где здесь проблема?
Вы должны указать в сериализаторе, что вы хотите, чтобы внешние ключи отображались в виде строк:
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
здесь же). Однако это может привести к проблемам с производительностью при работе с большими базами данных, поэтому не очень рекомендуется...