我正在为我的汽车共享应用程序使用Django Rest Framework构建API。我希望不让所有者用户有权更新比赛中的“参与者”字段,以便他们可以加入。其他字段应仅对所有者可用。我正在阅读有关django-guardian的信息,但我真的不了解如何实现它。这是我的模型:
from django.db import models
from django.contrib.auth.models import User
class Race(models.Model):
owner = models.ForeignKey("auth.User", related_name = 'races', on_delete=models.CASCADE)
origin_long = models.DecimalField(max_digits=8, decimal_places=3)
origin_lat = models.DecimalField(max_digits=8, decimal_places=3)
destination_long = models.DecimalField(max_digits=8, decimal_places=3)
destination_lat = models.DecimalField(max_digits=8, decimal_places=3)
start_time = models.TimeField(auto_now=False, auto_now_add=False)
participants = models.ManyToManyField(User,blank=True)
schedule = models.DurationField(blank=True,null=True)
subs = models.ManyToManyField(User, related_name='subs',blank=True)
cost = models.DecimalField(max_digits=5, decimal_places=2)
def __str__(self):
return self.user.get_full_name()
谢谢。
答案 0 :(得分:0)
我认为Django默认没有字段级权限。
但是我们可以通过serializers.py
和views.py
来调整和限制字段。
在views.py
class RaceUpdateView(UpdateAPIView):
lookup_field = 'pk'
serializer_class = RaceUpdateSerializer
queryset = Race.objects.all()
permission_classes = [IsAuthenticated]
model = Race
def put(self, request, pk):
try:
try:
race_obj = self.get_object()
except Exception as error:
context = {'error': "Race Id does not exist", 'success': "false", 'message': 'Race Id does not exist.'}
return Response(context, status=status.HTTP_404_NOT_FOUND)
#I don't know how you are checking owner. So i kept it this way.
if request.user.id != race_obj.owner.id:
#passing the fields which are to be used by the serializer.
serializer = RaceUpdateSerializer(race_obj, data=request.data, partial=True, fields=('participants',))
else:
serializer = RaceUpdateSerializer(race_obj, data=request.data, partial=True)
if serializer.is_valid():
try:
serializer.save()
except Exception as error:
context = {"success": False, "message": "Update Failed. %s" % str(error), "error": str(error)}
return Response(context, status=status.HTTP_400_BAD_REQUEST)
context = {"success": True, "message": "Updated Successful", "error": "", "data": serializer.data}
return Response(context, status=status.HTTP_200_OK)
context = {"success": False, "message": "Updated Failed, Invalid Input Data", "error": str(serializer.errors)}
return Response(context, status=status.HTTP_400_BAD_REQUEST)
except Exception as error:
context = {'error': str(error), 'success': "false", 'message': 'Failed To Update Race.'}
return Response(context, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
在serializers.py
class RaceUpdateSerializer(ModelSerializer):
class Meta:
model = Race
fields = '__all__'
def __init__(self, *args, **kwargs):
# Don't pass the 'fields' arg up to the superclass
fields = kwargs.pop('fields', None)
# Instantiate the superclass normally
super(RaceUpdateSerializer, self).__init__(*args, **kwargs)
if fields is not None:
# Drop any fields that are not specified in the `fields` argument.
allowed = set(fields)
existing = set(self.fields)
for field_name in existing - allowed:
self.fields.pop(field_name)
这样,在更新时仅使用从views.py
调用的提及字段。
serializer = RaceUpdateSerializer(race_obj, data=request.data, partial=True, fields=('participants',))
它将完成您要完成的任务。
注意-您也可以通过这种方式允许多个字段
serializer = RaceUpdateSerializer(race_obj, data=request.data, partial=True, fields=('field1','field2'))