2014-12-21 27 views
13

DurumEk Serializer Alanlar Django DİNLENME Çerçeve 3

Ben bir kullanıcı yaratılması için olanak tanıyan basit son nokta oluşturma. Kullanıcı modelimde olmayan bir alana ihtiyacım var (ör. confirm_password). Bu alanı ve benim modelimde bulunan başka bir alanı karşılaştıran doğrulama işlemini çalıştıracağım ve daha sonra seri hale getiricide ek alanı asla kullanmam.

Sorun

DRF sürüm 3, bunu başarmak için süreci değişti ve ben oldukça dokümantasyon yapmamı öneriyorsunuz ne anlamıyorum. Dokümantasyon için bkz. here. Şöyle bir UserSerializer yarattık

Çözüm de

Denemesi: Ben validate içinde confirm_password haşhaş sorunlarımı özen, ama sadece almak umuyordum

from django.contrib.auth import get_user_model 
from rest_framework import serializers 

class UserSerializer(serializers.ModelSerializer): 
    confirm_password = serializers.CharField(allow_blank=False) 

    def validate(self, data): 
     """ 
     Checks to be sure that the received password and confirm_password 
     fields are exactly the same 
     """ 
     if data['password'] != data.pop('confirm_password'): 
      raise serializers.ValidationError("Passwords do not match") 
     return data 

    def create(self, validated_data): 
     """ 
     Creates the user if validation succeeds 
     """ 
     password = validated_data.pop('password', None) 
     user = self.Meta.model(**validated_data) 
     user.set_password(password) 
     user.save() 
     return user 

    class Meta: 
     # returns the proper auth model 
     model = get_user_model() 
     # fields that will be deserialized 
     fields = ['password', 'confirm_password', 
        'username', 'first_name', 'last_name', 'email'] 
     # fields that will be serialized only 
     read_only_fields = ['is_staff', 'is_superuser'] 
     # fields that will be deserialized only 
     write_only_fields = ['password' 'confirm_password'] 

izleyen:

KeyError seri numarası UserSerializer numaralı alan için değer. Sana parola onayı görüntülemek istemiyor sanıyorum olarak serileştirici alan bir salt alanında aradığınız OrderedDict örneği

+0

Sadece bir kafaları yukarı, bu yaygın 'Meta' sınıfı, genellikle aradığınız bilgilerin çoğunu içerdiğinden, serileştiricinin en üstünde yer alır. –

+0

Ah, bu mantıklı. Bunu takdir ediyorum! – nmagerko

cevap

18

herhangi niteliğini veya anahtarı maç yanlış değil adlandırılmış olabilir API. Django REST Framework, read_only parametresini tamamlamak için 2.3.x zaman çizelgesindeki write_only parametresini tanıttı, böylece yalnızca zaman doğrulamanın çalıştırılması bir güncelleme yapıldığında gerçekleşir. write_only_fields meta özelliği aynı zamanda eklenmiştir, ancak bunların her ikisinin birlikte nasıl çalıştığını anlamak önemlidir. otomatik oluşturulduğunda

write_only_fields meta özelliği otomatik olarak User model üzerinde bir password alan için olduğu gibi, bir alana write_only özellik katacak. , modelde bulunmayan alanlar veya seri hale getiricide açıkça belirtilen alanlar için bunu yapmaz. Durumunuzda, toplayıcınızdaki confirm_password alanını açıkça belirtiyorsunuz, bu yüzden çalışmıyor. Got KeyError

serileştiriciden UserSerializer üzerine alanda confirm_password için bir değer elde etmek için çalışırken. serileştirici alan sizin confirm_password alan seri hale getirmek çalıştığında, OrderedDict Örneğin

Bu oluşturan kullanıcının yeniden seri hale getirme sırasında yükseltilir herhangi niteliğini veya anahtarı maç yanlış değil adlandırılmış olabilir. Alanı User modelinde bulamadığı için, bu sorunu açıklamaya çalışan bu hatayı tetikler. Ne yazık ki, bu yeni kullanıcısında olduğundan, User örneğinin yerine OrderedDict örneğine kafa karıştırıcı bir şekilde bakmanızı söyler.

class UserSerializer(serializers.ModelSerializer): 
    confirm_password = serializers.CharField(allow_blank=False, write_only=True) 

açıkça serileştirici sahada write_only belirtin ve sonra da senin bekliyoruz davranışı görmelisiniz, senin write_only_fields gelen alanını kaldırırsanız.

Kök modeli doğrudan sahip Kullanmak istediğiniz alanlara erişmez iç içe serileştirici uygulama temsil eden modeller için de yararlıdır bu link

0

, Bu konuda dokümanlarına ulaşabilirsiniz. @vyscond teşekkür ederiz; Bilginize burada böyledir): çoğu kişi koymak için

models.py

class Company(models.Model): 
    permission_classes = (
     IsCompanyMember, 
    ) 

    name = models.CharField(
     unique=True, 
     max_length=100, 
     verbose_name='company name', 
     null=False 
    ) 
class Profile(models.Model): 

    company = models.ForeignKey(Company, on_delete=models.CASCADE, null=True) 
    user = models.OneToOneField(User, on_delete=models.CASCADE) 
    is_company_admin = models.BooleanField(default=False, null=False) 
    is_email_validated = models.BooleanField(default=False, null=False) 
    is_approved_by_company_admin = models.BooleanField(default=False, null=False) 

serializer.py

class CompanySerializer(serializers.ModelSerializer): 
    class Meta: 
     model = Company 
     fields = ('name',) 

class CustomUserRegistrationSerializer(serializers.ModelSerializer): 
    password = serializers.CharField(style={'input_type': 'password'}, 
           write_only=True, 
           validators=settings.get('PASSWORD_VALIDATORS')) 

    company = CompanySerializer(allow_null=False, required=True,write_only=True) 

    class Meta: 
     model = User 
     fields = ('username', 
        'email', 
        'password', 
        'company', 
        'first_name', 
        'last_name') 
İlgili konular