Django REST Çerçevesinde alan adı nasıl değiştirilir


98

DRF Serializer'daki Model alan adını SQL'deki diğer ad gibi değiştirmeye çalışıyorum. Farklı yöntemler denedim ama başarılı olamıyorum.

models.py

class Park(models.Model):
    name = models.CharField(max_length=256)
    alternate_name = models.CharField(max_length=256, blank=True)
    objects = models.GeoManager()

    class Meta:
        db_table = u'p_park'

    def __unicode__(self):
        return '%s' % self.name

    def alias_alternate_name(self):
        return self.alternate_name

serializers.py

class ParkSerializer(serializers.ModelSerializer):

    location = serializers.Field(source='alias_alternate_name')
    #location = serializers.SerializerMethodField(source='alias_alternate_name')

    #alternate_name as location


    class Meta:
        model = Park
        fields = ('id', 'name', 'location')

Ayrıca Django Queryset'e takma ad eklemeyi denedim, ancak değiştirilemez.

Güncellenmiş

Bu karşı karşıya olduğum istisna

/ GörünümAdı / 'modül' nesnesinde AttributeError 'Alan' özniteliği yok

Bunu nasıl yapabilirim?


1
serializers.SerializerMethodFieldYaklaşımın doğru bir uygulamasını kullanıyor musunuz ? Bunu kastediyorum: serializers.SerializerMethodField('get_location')vedef get_location(self, obj): ...
erthalion

İthalatını görebilir miyiz serializers.py?
joerick

OP aşağıdaki daha iyi cevaplar yerine kısmen yanlış ve kafa karıştırıcı bir cevabı kabul ettiği için soruyu olumsuz oylayacak ...
NeuronQ

Yanıtlar:


59

Şunları kullanabilirsiniz serializers.SerializerMethodField:

İşte name ve alternate_name alanlarına sahip model Park.

class Park(models.Model):
    name = models.CharField(max_length=256)
    alternate_name = models.CharField(max_length=256, blank=True)
    objects = models.GeoManager()

    class Meta:
        db_table = u'p_park'

    def __unicode__(self):
        return '%s' % self.name

İşte Park Modeli için Seri Oluşturucu, ParkSerializer. Bu, alternate_name adını konum olarak değiştirir.

class ParkSerializer(serializers.ModelSerializer):
    location = serializers.SerializerMethodField('get_alternate_name')

    class Meta:
        model = Park
        fields = ('other_fields', 'location')

    def get_alternate_name(self, obj):
        return obj.alternate_name

Ayrıca, kullanabilirsiniz serializers.CharFieldile sourceöznitelik:

class ParkSerializer(serializers.ModelSerializer):
    location = serializers.CharField(source='other_fields')

    class Meta:
        model = Park
        fields = ('other_fields', 'location')

Django'nun __yabancı anahtarı geçmek için gösterimi de işe yarar:

location = serializers.CharField(source='OtherModel__other_fields')

API'deki dönüş türünü değiştirmek istiyorsanız, aynı ilke geçerlidir, böylece bunu serializers.DecimalField(source=...)ve diğer alan türlerini de değiştirebilirsiniz.

Ancak bu yalnızca salt okunur alanlar için çalışır.


Şimdi bu istisna / ViewName / 'modül' nesneye AttributeError atıyor hiçbir özelliği 'ni SerializerMethodField' vardır
-Shoaib Ijaz

1
Oluşturma ve düzenleme istekleri ile bu antrenman nasıl olur?
iankit

1
'Zen of Python'un 13 numaralı satırı: "Bunu yapmanın bir - ve tercihen sadece bir - açık yolu olmalıdır."
iankit

14
Kabul edilen cevap bu olmamalı. Aşağıdakine bakın, bunu yazdığım sırada neredeyse 5 kat daha fazla oy almış.
cderwin

6
Bu kötü bir çözüm. sourceBunun yerine kwarg'ı aşağıda açıklandığı gibi kullanın .
Patrick

215

Model alanından veri kaynağını belirleyebileceğiniz genel olarak 'kaynak' denilen serileştirici alanlarında ve serileştiricilerde çok güzel bir özellik var.

class ParkSerializer(serializers.ModelSerializer):
    location = serializers.SomeSerializerField(source='alternate_name')

    class Meta:
        model = Park
        fields = ('other_fields', 'location')

Burada serializers.SomeSerializerField, modelinizin önerdiği gibi serializers.CharField olabilir, ancak diğer alanlardan herhangi biri tarafından da yapılabilir. Bunun yerine ilişkisel alanları ve diğer serileştiricileri de koyabilirsiniz ve bu yine de cazibe gibi çalışacaktır. yani, alternate_name başka bir modele yabancı anahtar alanı olsa bile.

class ParkSerializer(serializers.ModelSerializer):
    locations = AlternateNameSerializer(source='alternate_name', many=true)

    class Meta:
        model = Park
        fields = ('other_fields', 'locations')

class AlternateNameSerializer(serializers.ModelSerialzer):
    class Meta:
        model = SomeModel

Bu, isteklerin oluşturulması, silinmesi ve değiştirilmesi ile de çalışır. Modellerde serileştiricide alan adı ve alan adının bire bir eşlemesini etkin bir şekilde oluşturur.


Kabul ettim, bu sourcedaha genel bir yaklaşım. Ancak soruda onu kullanmak için birkaç deneme görebilirsiniz, bu nedenle bu şekilde yanıtlamak istiyorsanız, orijinal kodun neden çalışmadığını da açıklamalısınız, değil mi?
erthalion

Kodunuz düzgün çalışacaktır .. istek listeleme ve geri alma için olduğu sürece
iankit

Her iki cevap da eksik. Yabancı anahtar durumunda, bu yöntem, yeni bir Park oluştururken, tüm ana nesneyi (alternate_name) POST isteğinizde bir dikte olarak vermeniz gerektiği anlamına gelir; bu, ana nesne zaten mevcut olduğundan deliliktir. Kimliği aracılığıyla yabancı durumdan bahsedilebilir.
stelios

Benim durumumda (yabancı anahtar) bu sorunu çözdüm locations = serializers.PrimaryKeyRelatedField(source='alternate_name', queryset=AlternateName.objects.all()). Görünüşe göre RelatedFieldde kullanılabilir.
stelios

@chefarov source = 'new_name' serileştirici alanlarına, ilişkilere ve diğer ilgili serileştiricilere vb. verebileceğiniz genel bir argümandır. Cevabın neden eksik olduğunu söylediğinizden emin değilim.
iankit

15

Bu, yazma işlemleri için de işe yarar

class ParkSerializer(serializers.ModelSerializer):
    location = serializers.CharField(source='alternate_name')

    class Meta:
        model = Park
        fields = ('id', 'name', 'location')
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.