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')liststrings 这样 ['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

有用的学习人员:

我发现错误了! \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 的帮助! :)