Dango Rest Framework: установите foreign_key, если условие выполнено - PullRequest
0 голосов
/ 09 мая 2018

Хи, я пишу Django Rest Framework API и постараюсь объяснить мою проблему на примере с двумя таблицами:

table1:

   id / user_id / album_name

table2

   id / user_id / table1_id / song_name
  • столбец user_id в обеих таблицах предназначен для хранения идентификатора пользователя, создавшего контент
  • id и user_id имеют условие unique_together в определении модели
  • table2 имеет много песен, и каждая песня может быть из одного альбома (table1)

Теперь, при создании новой песни в table2 я бы хотел установить foreign_key, который будет указывать на уже названный album в table1 НО ТОЛЬКО ЕСЛИ , что album создается тот же пользователь, который пытается создать новую песню

if user_id from table1 and user_id from current user are the same

Else there should be no foreign_key set for that song.

Я пытаюсь установить foreign_key в этом условии, чтобы сохранить изоляцию данных арендатора, чтобы песня из table2 не могла быть ошибочно подключена к альбому из table1, если один и тот же пользователь не создал оба альбома, а затем песня.

У меня нет проблем с установкой foreign_key для столбца user_id от активного пользователя, но я застрял на этом. Также я не нашел подобного примера в документации. Заранее благодарю за помощь.

models.py

class Album(models.Model):
    user = models.ForeignKey(User, on_delete=models.PROTECT)

    name = models.CharField(unique=True, max_length=100)

    class Meta:
        unique_together = ("id", "user")

class Song(models.Model):
    user = models.ForeignKey(User, on_delete=models.PROTECT)

    name = models.CharField(default='', max_length=50)
    album = models.ForeignKey(Album, null=True, blank=True, on_delete=models.PROTECT)

    class Meta:
        unique_together = ("id", "user")

serializers.py

class AlbumSerializer(serializers.ModelSerializer):
    class Meta:
        model = Album
        fields = ('name',)

class SongSerializer(serializers.ModelSerializer):
    album = serializers.PrimaryKeyRelatedField(many=False, read_only=True)
    class Meta:
        model = Song
        fields = ('name', 'album')

views.py

class SongList(generics.ListCreateAPIView):
    permission_classes = (permissions.IsAuthenticated,)
    serializer_class = SongSerializer

    def perform_create(self, serializer):
        serializer.save(user=self.request.user)

1 Ответ

0 голосов
/ 10 мая 2018

Измените serializer.py, как показано ниже,

class SongSerializer(serializers.ModelSerializer):
    class Meta:
        model = Song
        fields = ('name', 'album')

    def create(self, validated_data):
        if validated_data['album'].user == self.context.get('request').user:
            album = validated_data.pop('album')
            return Song.objects.create(**validated_data, album=album)
        raise serializers.ValidationError("There is no album related to current user")


Примечания :
1. Вы должны войти в систему перед выполнением операции
2. Вы можете изменить ошибку проверки и сделать что-то еще, если хотите
3. Вам не нужно указывать unique_together = ("id", "user") в моделях, потому что это никогда не произойдет (id равно PK,его никогда не повторяется, следовательно, id и user также)
4. Если я не ошибаюсь, представление SongList должно включать атрибут queryset или переопределять метод get_queryset().Иначе это вызовет AssertionError исключение

...