我在django工作,正计划为用户提供数据库。
每个 Ride 上可以有多个用户(乘客),其中包含多个中间目的地。 此外,每个目的地可以在多个游乐设施中,每个用户(乘客)可以在多个游乐设施(加班) )。
此外,对于每个 Ride ,只有一个最终目的地,只有一个驱动程序(也是用户)。
这是我的代码:
def get_image_path(models.Model):
return os.path.join('photos',str(instance.id),filename)
class UserProfile(models.Model):
user=models.OneToOneField(User)
phone_number=models.CharField(max_length=12)
profile_picture=models.ImageField(upload_to=get_image_path, black=True, null=True)
class Ride(models.Model):
driver=models.ForeignKey(UserProfile, related_name="r_driver")
destination=models.ForeignKey(Destination, related_name="r_final_destination")
leaving_time=models.DateTimeField()
num_of_spots=models.IntergerField()
passengers=models.ManyToMany(UserProfile, related_name="r_passengers")
mid_destinations=models.ManyToMany(Destination, related_name="r_mid_destinations")
class Destination(models.Model):
name=models.CharField(max_length=30)
问题 - 当用户添加Ride时,我希望驱动程序,目标和mid_destinations以及其他字段由设置用户(驱动程序为用户添加Ride), 乘客字段除。我希望其他用户将自己添加到骑行中,因此当创建骑行时,用户(驾驶员)不必设置乘客。
我该如何解决?还有关于模型的任何其他建议吗?
答案 0 :(得分:0)
问题是 - 当用户添加骑行时,我想要驱动程序,目的地 和mid_destinations以及用户设置的其余字段 (司机是用户添加乘车),乘客除外 字段。
您只需要一个自定义表单并手动处理driver
字段。像这样:
class DriverRideForm(forms.ModelForm):
class Meta:
model = Ride
exclude = ('driver', 'passengers', )
然后在view
request.user
是驱动程序
form = DriverRideForm(request.POST)
if form.is_valid():
ride = form.save(commit=False)
ride.driver = request.user.userprofile
ride.save()
您可以,但您可能不希望从driver
字段中排除serializer
。这是因为通常每ViewSet
只使用一个序列化程序,因此您需要将该字段返回给API的使用者。
所以你有两个选择:
将驱动程序字段更改为read-only
并挂钩perform_create
:
class RideSerializer(serializers.ModelSerializer):
class Meta:
model = Ride
read_only_fields = ('driver', 'passengers')
#inside your RideViewSet
def perform_create(self, serializer):
serializer.save(driver=self.request.user.userprofile)
在执行driver
之前将request.data
字段添加到.create
,而不更改序列化程序。
#inside your RideViewSet
def create(self, request, *args, **kwargs):
request.data['driver'] = self.request.user.userprofile
return super(RideViewSet, self).create(request, *args, **kwargs)
passengers
字段添加自己?我可能会使用自定义端点(@detail_route
)来实现。像这样:
class RideViewSet(...):
#...
@detail_route(methods=['post'])
def attach(self, request, pk=None):
ride = self.get_object()
ride.passengers.add(request.user.userprofile)
return Response(self.get_serializer(ride).data)
这样只需在url
/api/rides/<id>/attach/
进行发布,就会将登录的request.user
添加到ride.passengers
。
有关模特的其他建议吗?
我认为你的模型结构很好。我只能想到将来你可能需要更多关于这种关系的元数据,所以这可能是准备一些Intermediate Models
的好时机,例如:
class Ride(models.Model):
# ...
passengers=models.ManyToMany(UserProfile, through='RideSeat', related_name="r_passengers")
mid_destinations=models.ManyToMany(Destination, through='RideMidDestination', related_name="r_mid_destinations")
class RideSeat(models.Model):
ride = models.ForeignKey(Ride)
passenger = models.ForeignKey(UserProfile)
seat_number = models.IntegerField()
class RideMidDestination(models.Model):
ride = models.ForeignKey(Ride)
destination = models.ForeignKey(Destination)
arrival_time = models.DateTimeField()