2016-01-07 30 views
6

Django REST Framework ile basit bir model kaydetmek istiyorum. Tek gereksinim, UserVote.created_by'un perform_create() yönteminde otomatik olarak ayarlanmasıdır. Bu, bu durumla başarısız:Django REST Framework: "Bu alan gereklidir." required = False ve unique_together

{ 
    "created_by": [ 
     "This field is required." 
    ] 
} 

Ben çünkü unique_together endeksinin sanırım.

models.py:

class UserVoteSerializer(serializers.ModelSerializer): 
    id = serializers.IntegerField(read_only=True) 
    created_by = UserSerializer(read_only=True) 

    class Meta: 
     model = UserVote 
     fields = ('id', 'rating', 'created_by') 

views.py

class UserVoteViewSet(viewsets.ModelViewSet): 
    queryset = UserVote.objects.all() 
    serializer_class = UserVoteSerializer 
    permission_classes = (IsCreatedByOrReadOnly,) 

    def perform_create(self, serializer): 
     serializer.save(created_by=self.request.user) 

nasıl created_by kullanıcıdan girmesini kalmadan DRF benim modeli kaydedebilir

class UserVote(models.Model): 
    created_by = models.ForeignKey(User, related_name='uservotes') 
    rating = models.ForeignKey(Rating) 

    class Meta: 
     unique_together = ('created_by', 'rating') 

serializers.py ve bunun yerine bu alanı otomatik olarak kod olarak mı ayarladınız?

Şimdiden teşekkürler!

cevap

5

Benzer bir sorunla karşılaştım ve bunu açıkça yeni bir örneği seri hale getirme ve iletme yoluyla çözdüm. UserVoteViewSet size perform_createcreate yerini alacak vardır:

def create(self, request, *args, **kwargs): 
    uv = UserVote(created_by=self.request.user) 
    serializer = self.serializer_class(uv, data=request.data) 
    if serializer.is_valid(): 
     serializer.save() 
     return Response(serializer.data, status=status.HTTP_201_CREATED) 
    else: 
     return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) 
+1

Bu temiz! ÇALIŞIYOR bir cazibe gibi! İpucu için çok teşekkürler! –

+0

eksik ithalat. – Nisk

2

Yapabileceğiniz diğer garip yolu bu

@receiver(pre_save, sender=UserVote) 
def intercept_UserVote(sender, instance, *args, **kwargs): 
    import inspect 
    for frame_record in inspect.stack(): 
     if frame_record[3]=='get_response': 
      request = frame_record[0].f_locals['request'] 
      break 
    else: 
     request = None 

    instance.pre_save(request) 

gibi kullanım sinyalleri Sonra temelde Modelinizdeki pre_save tanımlayabilirsiniz olduğunu

def pre_save(self, request): 
    # do some other stuff 
    # Although it shouldn't happen but handle the case if request is None 
    self.created_by = request.user 

Bu sistemin avantajı, her model için aynı kodu kullanabilirsiniz. Herhangi bir şeyi değiştirmeniz gerekiyorsa sadece pre_save()'da değiştirin. Daha fazla şey ekleyebilirsiniz

İlgili konular