Django REST框架,处理创建记录的相关字段
初步说明:这是一个相当新的问题,尽管我还没有找到关于StackOverflow的充分答案;很多类似的问题,但不是这个。所以我要问一个新问题 问题是:当一个字段是现有记录的外键时,我很难创建记录,并且我不知道我在代码中犯了什么错误 在我的应用程序中,有两种模型存在疑问,即公司与资产负债表之间的一对多关系: 型号:Django REST框架,处理创建记录的相关字段,django,django-rest-framework,Django,Django Rest Framework,初步说明:这是一个相当新的问题,尽管我还没有找到关于StackOverflow的充分答案;很多类似的问题,但不是这个。所以我要问一个新问题 问题是:当一个字段是现有记录的外键时,我很难创建记录,并且我不知道我在代码中犯了什么错误 在我的应用程序中,有两种模型存在疑问,即公司与资产负债表之间的一对多关系: 型号: class Company(models.Model): cik = models.IntegerField(default=0, unique=True) symbol
class Company(models.Model):
cik = models.IntegerField(default=0, unique=True)
symbol = models.CharField(max_length=4, unique=True)
name = models.CharField(max_length=255, unique=True)
def __str__(self):
return self.symbol
class BalanceSheet(models.Model):
company = models.ForeignKey(Company,
null=True,
on_delete=models.CASCADE,
related_name='balance_sheets',)
date = models.DateField()
profit = models.BigIntegerField()
loss = models.BigIntegerField()
class Meta:
unique_together = (('company', 'date'),)
def __str__(self):
return '%s - %s' % (self.company, self.date)
class Company(models.Model):
cik = models.IntegerField(default=0)
symbol = models.CharField(max_length=4)
name = models.CharField(max_length=255)
def __str__(self):
return self.symbol
class BalanceSheet(models.Model):
company = models.ForeignKey(Company,
null=True,
on_delete=models.CASCADE,
related_name='balance_sheets',)
date = models.DateField()
profit = models.BigIntegerField()
loss = models.BigIntegerField()
class Meta:
unique_together = (('company', 'date'),)
def __str__(self):
return '%s - %s' % (self.company, self.date)
序列化程序:
class BalanceSheetSerializer(serializers.ModelSerializer):
company = serializers.StringRelatedField()
class Meta:
model = BalanceSheet
fields = ('company','date','profit','loss')
class CompanySerializer(serializers.ModelSerializer):
class Meta:
model = Company
fields = ('cik', 'symbol', 'name')
class CompanySerializer(serializers.ModelSerializer):
class Meta:
model = Company
fields = ('cik', 'symbol', 'name')
class BalanceSheetSerializer(serializers.ModelSerializer):
company = CompanySerializer(many=False)
class Meta:
model = BalanceSheet
fields = ('company', 'date', 'profit', 'loss')
def create(self, validated_data):
company_data = validated_data['company']
company, created = Company.objects.get_or_create(**company_data)
validated_data['company'] = company
sheet = BalanceSheet.objects.create(**validated_data)
return sheet
观点:
class BalanceSheetCreate(generics.CreateAPIView):
model = BalanceSheet
queryset = BalanceSheet.objects.all()
serializer_class = BalanceSheetSerializer
URL包括:
url(r'^(?P<symbol>[A-Z]{1,4})/create-balance-sheet/$', views.BalanceSheetCreate.as_view(),
name='create_balance_sheet'),
从该curl命令中删除公司数据会导致相同的错误
我如何避免这个错误?我想我是在告诉api我感兴趣的公司,无论是在url还是在post数据中
使用python3.6、django 1.11和djangorestframework 3.7.7您将获得
IntegrityError
,因为您的代码将尝试在没有公司的情况下创建新的资产负债表。这是因为StringRelatedField
是只读的(请参阅),因此在写入模式下使用BalanceSheetSerializer
时不会对其进行分析
您需要的是:
class BalanceSheetSerializer(serializers.ModelSerializer):
company = serializers.SlugRelatedField(slug_field='symbol')
class Meta:
model = BalanceSheet
fields = ('company','date','profit','loss')
回答我自己的问题,以下是我的结论。再次感谢你去dukebody
型号:
class Company(models.Model):
cik = models.IntegerField(default=0, unique=True)
symbol = models.CharField(max_length=4, unique=True)
name = models.CharField(max_length=255, unique=True)
def __str__(self):
return self.symbol
class BalanceSheet(models.Model):
company = models.ForeignKey(Company,
null=True,
on_delete=models.CASCADE,
related_name='balance_sheets',)
date = models.DateField()
profit = models.BigIntegerField()
loss = models.BigIntegerField()
class Meta:
unique_together = (('company', 'date'),)
def __str__(self):
return '%s - %s' % (self.company, self.date)
class Company(models.Model):
cik = models.IntegerField(default=0)
symbol = models.CharField(max_length=4)
name = models.CharField(max_length=255)
def __str__(self):
return self.symbol
class BalanceSheet(models.Model):
company = models.ForeignKey(Company,
null=True,
on_delete=models.CASCADE,
related_name='balance_sheets',)
date = models.DateField()
profit = models.BigIntegerField()
loss = models.BigIntegerField()
class Meta:
unique_together = (('company', 'date'),)
def __str__(self):
return '%s - %s' % (self.company, self.date)
序列化程序:
class BalanceSheetSerializer(serializers.ModelSerializer):
company = serializers.StringRelatedField()
class Meta:
model = BalanceSheet
fields = ('company','date','profit','loss')
class CompanySerializer(serializers.ModelSerializer):
class Meta:
model = Company
fields = ('cik', 'symbol', 'name')
class CompanySerializer(serializers.ModelSerializer):
class Meta:
model = Company
fields = ('cik', 'symbol', 'name')
class BalanceSheetSerializer(serializers.ModelSerializer):
company = CompanySerializer(many=False)
class Meta:
model = BalanceSheet
fields = ('company', 'date', 'profit', 'loss')
def create(self, validated_data):
company_data = validated_data['company']
company, created = Company.objects.get_or_create(**company_data)
validated_data['company'] = company
sheet = BalanceSheet.objects.create(**validated_data)
return sheet
我还必须将完整的公司数据作为嵌套dict包含在curl语句中。外键确实需要null=true
吗?不幸的是,切换该值不会改变任何结果。谢谢。这真的很有帮助,尽管我现在遇到了queryset问题。除了官方文档之外,您还知道编写API的资源吗?官方文件似乎是面向阅读的,在当时似乎已经过时了。(请参阅“检查关系”中的Python2样式打印语句)我不知道,如果您进行web搜索,有很多资源和教程。。。如果您有特定问题或不了解的内容,请将其发布到,以便人们能够帮助您。:)