在这里创建我的第一个Django应用。我在插入Route
对象时遇到问题。这是我的models.py
:
class Location(models.Model):
location_id = models.AutoField(primary_key=True)
location_name = models.CharField(max_length=50)
location_lat = models.FloatField()
location_log = models.FloatField()
def __str__(self):
return self.location_name
class Route(models.Model):
route_id = models.AutoField(primary_key=True)
route_code = models.CharField(max_length=50)
origin_location = models.OneToOneField(Location, related_name="origin", on_delete=models.PROTECT)
destination_location = models.OneToOneField(Location, related_name="destination", on_delete=models.PROTECT)
waypoint1_location = models.OneToOneField(Location, related_name="waypoint1", on_delete=models.PROTECT, blank=True, null=True)
waypoint2_location = models.OneToOneField(Location, related_name="waypoint2", on_delete=models.PROTECT, blank=True, null=True)
route_duration = models.DurationField(blank=True, null=True)
def __str__(self):
return self.route_code
我基本上想要的是拥有Route
,其中必须包含 origin 和 destination ,而航路点是可选的。
首先,我有一个表单页面,用户可以在其中单独创建Location
对象。
然后,我有另一个表单页面,用户可以在其中创建路线。它以Location
对象的形式选择-一个用于 origin ,一个用于 destination ,还可以选择 waypoint1 和 waypoint2 < / em>
因此,在创建Route
时,我显然不想创建一个新的Location
。它已经在那里。我只想将新的route
对象链接到已经存在的location
对象。
我的serializers.py
是:
class LocationSerializer(serializers.ModelSerializer):
class Meta:
model = Location
fields = '__all__'
class RouteSerializer(serializers.ModelSerializer):
origin_location = LocationSerializer(many=False, required=True)
destination_location = LocationSerializer(many=False, required=True)
waypoint1_location = LocationSerializer(many=False, required=False, read_only=True)
waypoint2_location = LocationSerializer(many=False, required=False, read_only=True)
class Meta:
model = Route
fields = '__all__'
要插入的route
JSON是:
{“ route_code”:“ 213123”,“ origin_location”:{“ location_id”:3,“ location_name”:“ Tumut”,“ location_lat”:-35.31158,“ location_log”:148.21159},“ destination_location”:{ “ location_id”:3,“ location_name”:“ Tumut”,“ location_lat”:-35.31158,“ location_log”:148.21159}}
我得到的错误是:
/ api / route / \ n上的AssertionError
.create()
方法不支持 默认情况下为可写的嵌套字段。\ n写一个明确的.create()
串行器planner.serializers.RouteSerializer
的方法,或设置read_only=True
在嵌套的序列化程序字段上。\ n \ n请求方法: POST \ n请求网址:http://localhost:8000/api/route/ \ n
好像我需要为我的create()
写一个RouteSerializer
函数,但是不确定如何处理它。
任何帮助表示赞赏。
答案 0 :(得分:1)
好的,我知道了。这是我的更改:
serializers.py
:
class LocationSerializer(serializers.ModelSerializer):
class Meta:
model = Location
fields = '__all__'
class RouteSerializer(serializers.ModelSerializer):
class Meta:
model = Route
fields = '__all__'
class RouteReadSerializer(RouteSerializer):
origin_location = LocationSerializer(read_only=True)
destination_location = LocationSerializer(read_only=True)
waypoint1_location = LocationSerializer(read_only=True)
waypoint2_location = LocationSerializer(read_only=True)
viewsets.py
class RouteViewSet(viewsets.ModelViewSet):
queryset = Route.objects.all()
serializer_class = RouteSerializer
def get_serializer_class(self):
# Define your HTTP method-to-serializer mapping freely.
# This also works with CoreAPI and Swagger documentation,
# which produces clean and readable API documentation,
# so I have chosen to believe this is the way the
# Django REST Framework author intended things to work:
if self.request.method in ['GET']:
# Since the ReadSerializer does nested lookups
# in multiple tables, only use it when necessary
return RouteReadSerializer
return RouteSerializer
class LocationViewSet(viewsets.ModelViewSet):
queryset = Location.objects.all()
serializer_class = LocationSerializer
models.py
class Route(models.Model):
route_id = models.AutoField(primary_key=True)
route_code = models.CharField(max_length=50, unique=True)
origin_location = models.ForeignKey(Location, related_name="origin", on_delete=models.CASCADE)
destination_location = models.ForeignKey(Location, related_name="destination", on_delete=models.PROTECT)
waypoint1_location = models.ForeignKey(Location, related_name="waypoint1", on_delete=models.PROTECT, blank=True, null=True)
waypoint2_location = models.ForeignKey(Location, related_name="waypoint2", on_delete=models.PROTECT, blank=True, null=True)
route_duration = models.DurationField(blank=True, null=True)
def __str__(self):
return self.route_code
我将OneToOneField
更改为ForeignKey
。这实际上更有意义。
谢谢