6

मैं gender, created_at, updated_at क्षेत्रों है कि एक अलग मॉडल UserProfile कहा जाता है में परिभाषित कर रहे हैं के साथ Django बाकी ढांचे (संस्करण 3.x.x) का विस्तार करने के कोशिश कर रहा हूँ बढ़ाएँ। जब मैं UserProfile मॉडल उदाहरण को अद्यतन करने का प्रयास करता हूं जिसमें नेस्टेड User मॉडल उदाहरण शामिल है, तो यह केवल UserProfile इंस्टेंस (gender, updated_at fields) अपडेट करता है।उपयोगकर्ता मॉडल Django बाकी ढांचे 3.x.x

class UserProfile(models.Model): 
     user = models.OneToOneField(User, primary_key = True, related_name = 'profile') 
     gender = models.CharField(choices = GENDERS, default = 2, max_length = 64) 
     created_at = models.DateTimeField(auto_now_add = True) 
     updated_at = models.DateTimeField(auto_now = True) 

     def __unicode__(self): 
       return self.user.username 

     @receiver(post_save, sender = User) 
     def create_profile_for_user(sender, instance = None, created = False, **kwargs): 
       if created: 
         UserProfile.objects.get_or_create(user = instance) 

     @receiver(pre_delete, sender = User) 
     def delete_profile_for_user(sender, instance = None, **kwargs): 
       if instance: 
         user_profile = UserProfile.objects.get(user = instance) 
         user_profile.delete() 

serializers.py:

class UserProfileSerializer(serializers.ModelSerializer): 

     id = serializers.IntegerField(source = 'pk', read_only = True) 
     username = serializers.CharField(source = 'user.username', read_only = True) 
     email = serializers.CharField(source = 'user.email') 
     first_name = serializers.CharField(source = 'user.first_name') 
     last_name = serializers.CharField(source = 'user.last_name') 

     class Meta: 
       model = UserProfile 
       fields = (
         'id', 'username', 'email', 'first_name', 'last_name', 
         'created_at', 'updated_at', 'gender', 
       ) 
       read_only_fields = ('created_at', 'updated_at',) 

     def update(self, instance, validated_data): 
       #user = User.objects.get(pk = instance.user.pk);   
       user = instance.user 
       user.email = validated_data.get('user.email', user.email) 
       user.first_name = validated_data.get('user.first_name', user.first_name) 
       user.last_name = validated_data.get('user.last_name', user.last_name) 
       user.save() 

       instance.gender = validated_data.get('gender', instance.gender) 
       instance.save() 

       return instance 

     def create(self, validated_data): 

       user_data = validated_data.pop('user') 
       user = User.objects.create(**user_data) 

       profile = UserProfile.objects.create(user = user, **validated_data) 
       return profile 

views.py तो बुनियादी तौर पर मैं क्या हासिल करना चाहते User मॉडल

models.py से email, first_name and last_name क्षेत्रों में भी अद्यतन करने के लिए सक्षम होने के लिए है :

class UserViewSet(viewsets.ModelViewSet): 
     queryset = User.objects.all() 
     serializer_class = UserSerializer 

class UserProfileViewSet(viewsets.ModelViewSet): 
     queryset = UserProfile.objects.all() 
     serializer_class = UserProfileSerializer 

उत्तर

4

यहां मैंने यह कैसे किया:

def update(self, instance, validated_data): 
    # First, update the User 
    user_data = validated_data.pop('user', None) 
    for attr, value in user_data.items(): 
      setattr(instance.user, attr, value) 
    # Then, update UserProfile 
    for attr, value in validated_data.items(): 
     setattr(instance, attr, value) 
    instance.save() 
    return instance 

असल में, मैं serializers (here, line 800) के लिए मूल कोड में देखा है और इसे संशोधित इतना है कि यह मेरी जरूरतों फिट होगा।

शुभकामनाएं।

+0

से निपटने के लिए लागू कर रहा हूँ कि कोई त्रुटि है, क्योंकि यह मुझे दे कि 'user' परिभाषित नहीं है, हो सकता है आप का मतलब' instance.user = user_data' – L3K0V

+0

वास्तव में, कि लाइन भी जरूरत नहीं है है, चूंकि सभी विशेषताओं को सीधे उपयोगकर्ता उदाहरण पर सेट किया जाता है। इसे हटा दें और इसे ठीक काम करना चाहिए :) – AdelaN

1

ऊपर कोड के साथ कोई भी जगह के लिए एक मामूली संशोधन {}

क्योंकि 'NoneType' वस्तु में कोई विशेषता 'आइटम'

def update(self, instance, validated_data): 
    # First, update the User 
    user_data = validated_data.pop('user', {}) 
    for attr, value in user_data.items(): 
     setattr(instance.user, attr, value) 
    # Then, update UserProfile 
    for attr, value in validated_data.items(): 
     setattr(instance, attr, value) 
    instance.save() 
    return instance 

एक और तरीका है कि मैं लागू करने कर रहा हूँ जो ख्याल रखता है सत्यापन के मैं PATCH

class UserSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = User 
     fields = ('email', 'first_name', 'last_name') 

class ProfileSerializer(serializers.ModelSerializer): 
    email = serializers.CharField(source='user.email') 
    first_name = serializers.CharField(source='user.first_name') 
    last_name = serializers.CharField(source='user.last_name') 

    class Meta: 
     model = Profile 
     exclude = ('user',) 

    def update(self, instance, validated_data): 
     user_data = validated_data.pop('user', {}) 
     user_serializer = UserSerializer(instance.user, data=user_data, partial=True) 
     user_serializer.is_valid(raise_exception=True) 
     user_serializer.update(instance.user, user_data) 
     super(ProfileSerializer, self).update(instance, validated_data) 
     return instance 
संबंधित मुद्दे