Django Rest - 未创建带有 SlugRelatedField 数据的 ManyToManyField
Django Rest - ManyToManyField with SlugRelatedField Data Is Not Being Created
我的数据库中有以下结构:
{
"name": "sum",
"formula": "a+b",
"date": "2020-01-17T19:02:24.143000Z",
"tags": [
"sum",
"test"
],
"latex": "a+b"
}
“tags”是TableCalculator中的一个字段,具有ManyToManyField关系。我使用了一个中间模型 (TagLink),它指定了多对多关系中涉及的计算器和标签模型的外键。
型号:
class Tag(models.Model):
name = models.CharField(max_length=25, primary_key=True, db_column='sTag')
class Meta:
db_table = 'tTag'
class Calculator(models.Model):
name = models.CharField(max_length=100, primary_key=True, db_column='sName')
formula = models.CharField(max_length=200, db_column='sFormula')
date = models.DateTimeField(auto_now=True, db_column='dtModifiedDate')
tags = models.ManyToManyField(Tag, through='TagLink', through_fields=('calculator', 'tag'), related_name='calculator', symmetrical=False)
class Meta:
db_table = 'tCalculator'
class TagLink(models.Model):
calculator = models.ForeignKey(Calculator, on_delete=models.CASCADE, db_column='sCalculator')
tag = models.ForeignKey(Tag, on_delete=models.CASCADE, db_column='sTag')
class Meta:
db_table = 'tTagLink'
auto_created = True
unique_together = [['calculator', 'tag']]
这里是 Serializer:
class TagSerializer(serializers.ModelSerializer):
class Meta:
model = Tag
fields = ['name']
class CalculatorSerializer(serializers.ModelSerializer):
tags = serializers.SlugRelatedField(
many=True, queryset=Tag.objects.all(), slug_field='name')
class Meta:
model = Calculator
fields = ['name', 'formula', 'date', 'tags']
def create(self, validated_data):
tags = validated_data.pop('tags')
calculadora = self.Meta.model.objects.create(**validated_data)
for tag in tags:
obj, _ = Tag.objects.get_or_create(name=tag)
calculadora.tags.add(obj)
calculadora.save()
return calculadora
-> 我在 create() 方法中创建新“标签”时遇到问题;
(1) 成功条件: 如果标签已存在于数据库中则创建成功 (TagLink table):
(Pdb) calc_serializer.data
{'name': 't4', 'formula': 'r', 'date': '2020-01-17T18:54:18.448332Z', 'tags': ['erika'], 'inputs': [OrderedDict([('name', 'r'), ('calculatorName', 't4'), ('isCalculator', False), ('isArray', False), ('isMatrix', False)])]}
(2) 失败条件: 如果数据库中不存在标签,则不会创建标签,我会收到以下错误“CalculatorNotFound”:
return CalculatorNotFoundException(logger, request_json['name']).response
Ps.: calc_serializer.data returns 正确。但是正在发生的事情是 calc_serializer 没有验证。
有人可以帮我解决这个错误吗?我整天都在试图找出答案! :/
非常感谢!!!
你的代码是说如果我有一个现有的标签与计算器建立关系,你不需要验证 Tag
是否存在你可以简单地使用 get_or_create
method 来获取现有的 Tag
或创建一个新的,您还试图在 Calculator
模型关系中添加 string
,请记住在您的情况下 validated_data.pop('tags')
是 list
的 strings
这样 ['erika']
def create(self, validated_data):
tags = validated_data.pop('tags')
calculadora = self.Meta.model.objects.create(**validated_data)
for tag in tags:
# return the Tag object model
obj, _ = Tag.objects.get_or_create(name=tag)
calculadora.tags.add(obj)
calculadora.save()
return calculadora
有用的学习人员:
- 详细了解
add
method
- 了解更多关于字典 pop method
- 从 DRF
了解有关 nested representation 的更多信息
我发现错误了! \o/
我纠正了失败情况(如果数据库中不存在标签)。我做了以下事情:
在保存计算器之前,我首先将标签保存到数据库中。这样,我就可以更新标签了!!!!
for tag_name in request_json['tags']:
tag_object = Tag.objects.get_or_create(name=tag_name)
tag_serializer = TagSerializer(data={'name': tag_name}) # -> I save first to the database
calc_serializer = CalculatorSerializer(data=request_json)
if calc_serializer.is_valid():
calc_serializer.save()
response = JsonResponse(
calc_serializer.data, status=status.HTTP_201_CREATED)
return response
特别感谢@DaviWesley 的帮助! :)
我的数据库中有以下结构:
{
"name": "sum",
"formula": "a+b",
"date": "2020-01-17T19:02:24.143000Z",
"tags": [
"sum",
"test"
],
"latex": "a+b"
}
“tags”是TableCalculator中的一个字段,具有ManyToManyField关系。我使用了一个中间模型 (TagLink),它指定了多对多关系中涉及的计算器和标签模型的外键。
型号:
class Tag(models.Model):
name = models.CharField(max_length=25, primary_key=True, db_column='sTag')
class Meta:
db_table = 'tTag'
class Calculator(models.Model):
name = models.CharField(max_length=100, primary_key=True, db_column='sName')
formula = models.CharField(max_length=200, db_column='sFormula')
date = models.DateTimeField(auto_now=True, db_column='dtModifiedDate')
tags = models.ManyToManyField(Tag, through='TagLink', through_fields=('calculator', 'tag'), related_name='calculator', symmetrical=False)
class Meta:
db_table = 'tCalculator'
class TagLink(models.Model):
calculator = models.ForeignKey(Calculator, on_delete=models.CASCADE, db_column='sCalculator')
tag = models.ForeignKey(Tag, on_delete=models.CASCADE, db_column='sTag')
class Meta:
db_table = 'tTagLink'
auto_created = True
unique_together = [['calculator', 'tag']]
这里是 Serializer:
class TagSerializer(serializers.ModelSerializer):
class Meta:
model = Tag
fields = ['name']
class CalculatorSerializer(serializers.ModelSerializer):
tags = serializers.SlugRelatedField(
many=True, queryset=Tag.objects.all(), slug_field='name')
class Meta:
model = Calculator
fields = ['name', 'formula', 'date', 'tags']
def create(self, validated_data):
tags = validated_data.pop('tags')
calculadora = self.Meta.model.objects.create(**validated_data)
for tag in tags:
obj, _ = Tag.objects.get_or_create(name=tag)
calculadora.tags.add(obj)
calculadora.save()
return calculadora
-> 我在 create() 方法中创建新“标签”时遇到问题;
(1) 成功条件: 如果标签已存在于数据库中则创建成功 (TagLink table):
(Pdb) calc_serializer.data
{'name': 't4', 'formula': 'r', 'date': '2020-01-17T18:54:18.448332Z', 'tags': ['erika'], 'inputs': [OrderedDict([('name', 'r'), ('calculatorName', 't4'), ('isCalculator', False), ('isArray', False), ('isMatrix', False)])]}
(2) 失败条件: 如果数据库中不存在标签,则不会创建标签,我会收到以下错误“CalculatorNotFound”:
return CalculatorNotFoundException(logger, request_json['name']).response
Ps.: calc_serializer.data returns 正确。但是正在发生的事情是 calc_serializer 没有验证。
有人可以帮我解决这个错误吗?我整天都在试图找出答案! :/
非常感谢!!!
你的代码是说如果我有一个现有的标签与计算器建立关系,你不需要验证 Tag
是否存在你可以简单地使用 get_or_create
method 来获取现有的 Tag
或创建一个新的,您还试图在 Calculator
模型关系中添加 string
,请记住在您的情况下 validated_data.pop('tags')
是 list
的 strings
这样 ['erika']
def create(self, validated_data):
tags = validated_data.pop('tags')
calculadora = self.Meta.model.objects.create(**validated_data)
for tag in tags:
# return the Tag object model
obj, _ = Tag.objects.get_or_create(name=tag)
calculadora.tags.add(obj)
calculadora.save()
return calculadora
有用的学习人员:
- 详细了解
add
method - 了解更多关于字典 pop method
- 从 DRF 了解有关 nested representation 的更多信息
我发现错误了! \o/
我纠正了失败情况(如果数据库中不存在标签)。我做了以下事情: 在保存计算器之前,我首先将标签保存到数据库中。这样,我就可以更新标签了!!!!
for tag_name in request_json['tags']:
tag_object = Tag.objects.get_or_create(name=tag_name)
tag_serializer = TagSerializer(data={'name': tag_name}) # -> I save first to the database
calc_serializer = CalculatorSerializer(data=request_json)
if calc_serializer.is_valid():
calc_serializer.save()
response = JsonResponse(
calc_serializer.data, status=status.HTTP_201_CREATED)
return response
特别感谢@DaviWesley 的帮助! :)