2017-07-02 110 views
1

我使用Django 1.11和Django Rest Framework來創建API,用戶可以在其中創建和更新與django用戶模型相關的員工。
該精簡的代碼,我已經有了如下:DRF序列化程序更新嵌套用戶

我有了這個模型:

class Employee(models.Model): 
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='employee') 
    uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) 

這兩個viewsets:

class UserViewSet(viewsets.ModelViewSet): 
    serializer_class = serializers.UserSerializer 
    permission_classes = [permissions.IsAuthenticated] 

class EmployeeViewSet(viewsets.ModelViewSet): 
    serializer_class = serializers.EmployeeSerializer 
    permission_classes = [permissions.IsAuthenticated] 

和這兩個序列化器:

class UserSerializer(serializers.HyperlinkedModelSerializer) 
    class Meta 
     models = User 
     fields = ('url', 'id', 'username', 'email', 'is_staff', 'first_name', 'last_name', 'password') 
     read_only_field = ('id',) 

    def validate(self, data) 
     # ... Check if data is valid and if so... 
     return data 

class EmplyoeeSerializer(serializers.HyperlinkedModelSerializer): 
    user = UserSerializer() 
    class Meta: 
     model = Employee 
     field = ('url', 'uuid', 'user') 
     read_only_field = ('uuid') 

    def validate(self, data): 
     return data 

    def create(self, validated_data): 
     user = User(**validated_data['user']) 
     user.save() 
     employee = Employee(user=user) 
     employee.save() 
     return employee 

    def update(self, employee, user): 
     employee.user.username = user.username 
     employee.user.email = user.email 
     employee.user.first_name = user.first_name 
     employee.user.last_name = user.last_name 
     employee.user.is_staff = user.is_staff 
     # ... Check if password has changed, and if so... 
     employee.user.set_password(user.password) 
     employee.user.save() 
     employee.save() 
     return employee 

也是我在我的urls.py

router = routers.DefaultRouter() 
router.register(r'api/user', views.UserViewSet, base_name='user') 
router.register(r'api/employee', views.UserViewSet, base_name='employee') 

了這兩個路由器創建和更新的用戶實例是沒有問題的。
我也可以創建一個員工,作爲回報,他將創建一個用戶,然後創建一個僱員給該用戶。
我甚至可以更新員工的用戶名,用戶也會更新,
但我無法更新first_name,last_name,email,is_staff和密碼。
DRF不斷告訴我用戶名已被佔用,但是當我更改用戶名和其他信息(如first_name和last_name),然後向服務器發送PUT請求時,員工和關聯的用戶實例得到正確更新。
我錯過了什麼?
爲什麼我不能更新員工用戶實例,就像我可以在用戶api端點上更新普通用戶實例一樣? :/

在此先感謝,
任何幫助,將不勝感激。

回答

0

最後,我發現我失蹤了。
UserSerializers將django.contrib.auth.validators.UnicodeUsernameValidatorUniqueValidator添加到字段用戶名,每次執行放入請求時都會進行檢查。
向UserSerializer的Meta類添加validators = []解決了我的問題。

+0

你應該仍然保留'django.contrib.auth.validators.UnicodeUsernameValidator'。它應該是'validators = [django.contrib.auth.validators.UnicodeUsernameValidator]'。只留下'UniqueValidator'。 – cezar