2017-07-02 4 views
1

Ich benutze Django 1.11 und das Django Rest Framework, um eine API zu erstellen, wo ein Benutzer einen Mitarbeiter erstellen und aktualisieren kann, der mit dem django Benutzermodell verwandt ist.
Die abgespeckte Code, den ich habe sieht wie folgt aus:DRF Serializer Update verschachtelter Benutzer

ich dieses Modell haben:

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) 

diese beiden Viewsets:

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

und

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

und diese zwei Serialisierer:

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 

und

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 

auch habe ich diese beiden Router in meinem urls.py bekam

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

Erstellen und eine Instanz des Benutzers zu aktualisieren ist kein Problem.
Ich kann auch einen Mitarbeiter erstellen, der im Gegenzug einen Benutzer und dann eine Mitarbeiterzuweisung für diesen Benutzer erstellen wird.
Ich kann sogar den Benutzernamen des Mitarbeiters aktualisieren und der Benutzer wird auch aktualisiert,
, aber ich kann Vorname, Nachname, E-Mail, Is_staff und Passwort nicht aktualisieren.
DRF teilt mir mit, dass der Benutzername bereits vergeben ist, aber wenn ich den Benutzernamen und andere Informationen wie Vorname und Nachname ändere und dann eine Anfrage an den Server sende, werden der Mitarbeiter und die zugehörige Benutzerinstanz korrekt aktualisiert.
Was fehlt mir?
Warum kann ich die Benutzerinstanz der Mitarbeiter nicht aktualisieren, so wie ich die normale Benutzerinstanz aktualisieren kann, wenn ich am Endpunkt der Benutzer-API bin? :/

Vielen Dank im Voraus,
jede Hilfe wäre willkommen.

Antwort

0

Endlich fand ich heraus, was ich vermisste.
Der UserSerializers fügt dem Feld username django.contrib.auth.validators.UnicodeUsernameValidator und UniqueValidator hinzu, die jedes Mal überprüft wird, wenn ich eine Put-Anfrage mache.
Das Hinzufügen von validators = [] zur Meta-Klasse von UserSerializer löste mein Problem.

+0

Sie sollten 'django.contrib.auth.validators.UnicodeUsernameValidator' weiterhin speichern. Es sollte "validators = [django.contrib.auth.validators.UnicodeUsernameValidator]" sein. Lassen Sie nur 'UniqueValidator' aus. – cezar

Verwandte Themen