Сериализатор обратных отношений Django - PullRequest
0 голосов
/ 03 января 2019

Я пытаюсь создать проект для самообучения, и сейчас я застрял в этой точке.

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

Например, как организатор я могу сказать, что у меня будут "Цыпленок", "Турция" и "Говядина" со стола MeatType, в котором есть "Цыпленок", "Турция" и "Свинина". (Организатор создаст новый MeatType и выберет его для своего мероприятия)

Итак, у меня есть 3 модели Джанго, связанные с этой конкретной проблемой.

Модель события :

class Event(models.Model):
   name = models.CharField(_('Event name'), max_length=255)
   capacity = models.IntegerField(_('Capacity'), null=True)
   address = models.CharField(_('Address'), max_length=255)
   date = models.DateTimeField(_('Event Date'), db_index=True)

   organizer = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=_('Organizer'), related_name='events',
                              on_delete=models.CASCADE)

Тип мяса модель :

class MeatType(models.Model):
   """
   A model just to hold meat type names on the database.
   This model will only have a "name" field which represents the Meat Type.
   For example, "Chicken" or "Beef"
   """
   name = models.CharField(_('Name'), max_length=255)

и Доступный тип мяса Модель :

class AvailableMeatType(models.Model):
    """
    Available meat types for the event selected by Organizer
    """
    event = models.ForeignKey(Event, verbose_name=_('Event'), related_name='available_meat_types',
                          on_delete=models.CASCADE)
    meat_type = models.ForeignKey(MeatType, verbose_name=_('Meat Type'), on_delete=models.CASCADE)

Согласно этой структуре, для создания мероприятия организатор должен отправить запрос в следующем виде:

    {
       "name": "Team BBQ",
       "capacity": 10,
       "address": "Down Town",
       "date": "2019-02-01T18:00",
       "available_meat_type_ids": [
           1, 
           2, 
           3
       ]    
    }

Где 1, 2 и 3 - идентификаторы Meat Type, но будут создаваться Available Meat Type объекты, такие как: {123, 1}, {123, 2}, {123, 3}, где 123 - идентификатор созданного события

** Мои сериализаторы **

class EventSerializer(serializers.ModelSerializer):
    """
    A serializer class for creating and listing events
    """
    organizer = serializers.PrimaryKeyRelatedField(read_only=True)
    available_meat_type_ids = serializers.PrimaryKeyRelatedField(
    many=True,
    read_only=True
)

    class Meta:
        model = Event
        fields = (
            'id',
            'name',
            'capacity',
            'address',
            'date',
            'organizer',
            'available_meat_type_ids'
        )
        read_only_fields = ('organizer', )

    def post(self, request, *args, **kwargs):
        """
        Create available meat type object
        """
        # I dont know what to do here
        pass

    @staticmethod
    def validate_date(date):
        # Date of the event can not be on the past
        if date < timezone.now():
            raise Exception("Date of the new event can not be on the past.")
        return date


class CreateAvailableMeatTypeSerializer(serializers.ModelSerializer):
    """
    A serializer for available meat type request.
    """
    event = serializers.PrimaryKeyRelatedField(required=True, queryset=Event.objects)
    meat_type = serializers.PrimaryKeyRelatedField(required=True, queryset=MeatType.objects)

    class Meta:
        model = AvailableMeatType
        fields = (
            'id',
        )

Я не знаю, как заставить это работать. Я пытался найти в Интернете, но не смог найти ничего, что помогло бы.

Как я могу создать доступные объекты типа мяса из идентификаторов типа мяса, которые я получаю в запросе на создание события?

1 Ответ

0 голосов
/ 03 января 2019

Я думаю, что вы можете просто сделать это следующим образом:

class EventSerializer(serializers.ModelSerializer):

    organizer = serializers.PrimaryKeyRelatedField(read_only=True)
    available_meat_type_ids = serializers.PrimaryKeyRelatedField(
        many=True,
        read_only=True
    )
    meat_id = serailizers.IntegerField()

    class Meta:
        model = Event
        fields = (
            'id',
            'name',
            'capacity',
            'address',
            'date',
            'organizer',
            'available_meat_types',
            'meat_id'
        )
        read_only_fields = ('organizer', )
        write_only_fields = ('meat_id',)

    def create(self, validate_data):
      meat_id = validate_data.pop('meat_id')
      event = Event.objects.create(**validate_data)
      AvailableMeatType.objects.create(event=event, meat_type_id=meat_id)
      return event

Для получения более подробной информации, пожалуйста, проверьте документацию на PrimaryKeyRelatedField.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...