我正在尝试创建一个API,用于在数据库表中添加项目。我当前的代码是https://github.com/scaltro/youtubeapp/blob/master/myupload/views.py。
问题是,当我尝试在api http://142.93.130.167:1080/api/titles中发布数据时,出现此错误:
无法分配“ 1”:“ TitleVideoModel.video_id”必须是“ VideosModel”实例
怎么了?我该如何解决该错误?
答案 0 :(得分:1)
问题是您试图将一个整数(可以是VideosModel
的ID,也可以只是一个随机整数)分配到外键字段中。
查看您的代码,我会修复许多非Django的问题:
Group
表示),即VideosModel
应该为VideoModel
。Model
;显然他们是模特。 (考虑Django的内置User
。它不是UserModel
)。因此,要添加到上面:将VideosModel
仅设为Video
。ForeignKey
字段不应以_id
结尾。它们不是ID字段 sich ,即使它们在幕后由ID字段(恰好称为FIELDNAME_id
)支持-也就是说,您的模型将具有物理数据库名为video_id_id
的字段。
因此,TitleVideoModel.video_id
应该只是video
。然后有非DRFism。您实际上应该将rest_framework.viewsets.ModelViewSet
/ TitlesList
/ TitleDetail
用作TitlesView
,然后将获得为验证而手动编写的所有代码这些序列化程序,并为值等设置默认值。
我建议阅读视图集上的DRF tutorial。
答案 1 :(得分:0)
fuentes fuente2 = new fuentes { referencia = "CE18M", modelo = "MEANWELL", voltaje = 12, potencia = 18, ip = 67, factorpotencia = 0.5, precio = 14 };
fuentes fuente7 = new fuentes { referencia = "CE36M", modelo = "MEANWELL", voltaje = 12, potencia = 36, ip = 67, factorpotencia = 0.5, precio = 26 };
fuentes fuente9 = new fuentes { referencia = "CE60M", modelo = "MEANWELL", voltaje = 12, potencia = 60, ip = 67, factorpotencia = 0.5, precio = 29.5 };
fuentes fuente14 = new fuentes { referencia = "CE120M", modelo = "MEANWELL", voltaje = 12, potencia = 120, ip = 67, factorpotencia = 0.5, precio = 76.62 };
List<double> units = new List<double>();
List<double> fuentesexterior = new List<double>() { fuente14.potencia, fuente12.potencia, fuente9.potencia, fuente7.potencia, fuente2.potencia};
calculofuentesexterior(units, fuentesexterior, 0, 0, totalwatios);
}
static void calculofuentesexterior(List<double> units, List<double> fuentesexterior, double highest, double sum, double goal)
{
if (sum <= (goal + (goal * 25 / 100)) && sum >= (goal + (goal * 15 / 100)))
{
pintafuentesexterior(units, fuentesexterior);
return;
}
if (sum > (goal + (goal * 25 / 100)))
{
return;
}
foreach (double value in fuentesexterior)
{
if (value >= highest)
{
List<double> copy = new List<double>(units);
copy.Add(value);
calculofuentesinterior(copy, fuentesexterior, value, sum + value, goal);
}
}
}
static void pintafuentesexterior(List<double> units, List<double> amounts)
{
foreach (double fuentesexterior in amounts)
{
double count = units.Count(value => value == fuentesexterior);
Console.WriteLine("{0}: {1}",
fuentesexterior,
count);
}
Console.WriteLine();
Console.ReadKey();
}
必须是video_id
的实例,因此请替换:
VideosModel
作者:
video_id = video_id
答案 2 :(得分:0)
您必须传递VideosModel
的对象,以便Django可以通过关系对其进行映射。因此,在TitlesView
中,您可以执行以下操作:
try:
video = VideosModel.objects.get(id=video_id)
t = TitleVideoModel(
title=title,
video=video,
publicato=publicato,
youtube_url=youtube_url,
author=author,
created_at=created_at,
updated=updated_at,
)
except VideosModel.DoesNotExist:
# Handle the case when video by id is not found.
答案 3 :(得分:0)
ForeignKey
名称问题实际上更多地位于models.py
中,而不是views.py
中。 Django开发人员经常犯的一个错误是写类似这样的东西:
class TitleVideoModel(models.Model): # ... video_id = models.ForeignKey(VideosModel, on_delete=models.PROTECT)
在这里,您定义了一个ForeignKey
实例,该实例引用了一个VideosModel
实例。现在,这当然会在数据库中存储为一列,该列引用VideosModel
表的主键值),但是在Django级别上,这实际上是对{{1}的(惰性)引用}对象。因此,名称应为VideosModel
,而不是video
:
videos
为什么那么重要?因为对于class TitleVideoModel(models.Model):
# ...
video = models.ForeignKey(VideosModel, on_delete=models.PROTECT)
,Django具有两个属性:ForeignKey
和video
(在旧版本中为video_id
,但是那是一个丑陋的名称)。 video_id_id
懒惰地引用了video
实例,它的双胞胎VideosModel
存储了主键。实际上,video_id
属性有点“虚拟”,因为在数据库中仅存在video
。
因此,您可以通过简单地编写以下内容来设置主键,而无需首先对该对象进行提取:
video_id
,然后您可以直接更新参考。由于Django添加了外键约束,因此如果some_titlevideomodel.video_id = 123
some_titlevideomodel.save()
不是有效的主键值,这也会出错。过滤,更新,创建等操作也会发生同样的情况。编写123
时,它将接受一个主键值(默认情况下,主键是一个整数),并因此使用该值。
我建议您重命名该关系并构建迁移,因为这更多的是Django风格。
video_id
如果您不想重命名video_id_id
,可以将其重写为:
ForeignKey
但这最终只会导致更多的混乱。尽管现在需要一些工作来解决这种情况,但我认为最后,您的努力很值得。
注意:Django风格还指定模型应具有单数名称,并且通常 not 以
t = TitleVideoModel( title=title, video_id_id=video_id, publicato=publicato, youtube_url=youtube_url, author=author, created_at=created_at, updated=updated_at )
结尾,因此Model
代替TitleVideo
,而TitleVideoModel
代替Video
。