В документации DRF:

Обычно вы хотите убедиться, что вы установили соответствующий аргумент related_name для отношения, которое вы можете использовать в качестве имени поля.

Если вы не задали связанное имя для обратной связи, вам нужно будет использовать автоматически сгенерированное связанное имя в аргументе fields.

Модель My Room имеет следующее:

hotel = models.ForeignKey(
    Hotel,
    related_name="%(class)s_rooms",
    verbose_name=u'Hotel') 

Как добавить это в отель сериализатор? Я пытался fields = ('room_set', ...), но я получаю

Неправильно настроен в / api / hotel / Имя поля room_set не действительно для модели Hotel.

0
Hisham 21 Авг 2018 в 15:22

3 ответа

Лучший ответ

Связанное имя Hotel в классе модели Room разрешается как hotel_rooms. Если вы хотите включить в класс сериализатора отношение, вы можете попробовать что-то вроде этого:

class HotelSerializer(serializers.ModelSerializer):
    # as of the updates based on your comments this may become obsolete
    hotel_rooms = serializers.PrimaryKeyRelatedField(
        many=True,
        read_only=True
    )

    class Meta:
        model = Hotel
        fields = ('hotel_rooms',) # put all other fields you need
        # add depth for displaying nested contents
        depth = 1

ОБНОВИТЬ:

В моем первом предложении есть ошибка. related_name разрешается не в hotel_rooms, а в room_rooms, предполагая, что имя класса - Room. related_name должен быть осмысленным, и в этом случае hotel_rooms или даже просто rooms имеет смысл. Когда у вас есть отель, вы можете запросить номер в гостинице:

hotel = Hotel.objects.get(pk=1)
hotel.hotel_rooms.all() # or hotel.rooms.all()

Вы не выявили необходимость использования %(class)s_rooms. Имеет смысл использовать его в абстрактных классах, которые будут унаследованы от других классов моделей или при использовании среды ContentType, где имя класса actall еще не известно во время объявления related_name.

0
cezar 21 Авг 2018 в 13:11

Используйте fields = ('modelname_rooms', ...)

Предполагая, что у вас есть класс модели как,

class Hotel(models.Model):
    name = models.CharField(max_length=123)


class MyModel(models.Model):
    hotel = models.ForeignKey(Hotel, related_name="%(class)s_rooms", verbose_name=u'Hotel')

И в вашем HotelSerializer,

class HotelSerializer(serializers.ModelSerializer):
    class Meta:
        model = Hotel
        fields = ("mymodel_rooms",)

То есть вам нужно добавить префикс в _room , чтобы использовать related_field. Здесь prefix - это имя класса модели в lower case буквах .

1
JPG 21 Авг 2018 в 13:08

Слишком большой для комментариев. Но не могли бы вы проверить, что related_name кажется, что есть проблема с форматом, если вы не укажете его намеренно.

hotel = models.ForeignKey(
    Hotel,
    related_name="abcs_rooms", # update this line
    verbose_name=u'Hotel') 
0
argo 21 Авг 2018 в 12:48
51948609