Я работаю над "менеджером хранилища", в основном у меня есть 3 модели:
- Набор данных
- Файл
- Автор (может быть автором файл или один из авторов набора данных)
Автор
class Author(models.Model):
name = models.CharField(max_length=50)
surname = models.CharField(max_length=50)
email = models.EmailField()
phone = models.CharField(max_length=20, blank=True)
class Meta:
unique_together = (("name", "surname", "email"),)
Набор данных
class Dataset(models.Model):
token = models.CharField(max_length=300, unique=True)
name = models.CharField(max_length=150, unique=True)
description = models.TextField(blank=True)
slug = models.SlugField(max_length=200, blank=True, unique=True)
authors = models.ManyToManyField(Author, related_name='author')
remote = models.URLField(max_length=300)
Файл
class File(models.Model):
creator = models.ForeignKey(Author, related_name='creator', null=True, on_delete=models.SET_NULL)
dataset = models.ForeignKey(Dataset, related_name='dataset', on_delete=models.CASCADE)
path = models.CharField(max_length=200, default="", blank=True, null=True)
name = models.CharField(max_length=100)
description = models.CharField(max_length=300, blank=True)
url = models.URLField(max_length=300)
Итак, у меня есть Dataset
, принадлежащий одному или нескольким Author
, который состоит из множества File
. Хотя создание / обновление наборов данных и авторов работает хорошо, я сталкиваюсь с некоторыми трудностями при обработке файлов и, в частности, при добавлении / удалении файлов.
В настоящий момент мне удалось написать API, который удаляет все файлы и позволяет нам «повторно загрузить» весь набор файлов набора данных. Но я бы предпочел разрешить только частичные обновления / вставки.
Вот мои сериализаторы:
</p>
<code>class AuthorSerializer(serializers.ModelSerializer):
class Meta:
model = Author
fields = ('name', 'surname', 'email', 'phone')
class FileSerializer(serializers.ModelSerializer):
creator = AuthorSerializer(required=False)
class Meta:
model = File
fields = ('pk', 'name', 'description', 'url', 'creator')
class DatasetSerializer(serializers.ModelSerializer):
authors = AuthorSerializer(many=True)
files = FileSerializer(required=False, many=True)
class Meta:
model = Dataset
fields = ['pk', 'name', 'description', 'remote', 'authors', 'files']
@transaction.atomic()
def create(self, validated_data):
try:
files_list = validated_data.pop('files')
except KeyError:
files_list = []
try:
authors_data = validated_data.pop('authors')
except KeyError:
authors_data = []
dataset = Dataset.objects.create(**validated_data)
for author in authors_data:
# for each author
author_, created = Author.objects.get_or_create(**author)
dataset.authors.add(author_)
for file in files_list:
if 'creator' in file:
file_creator_data = file.pop('creator')
file_creator, created = Author.objects.get_or_create(**file_creator_data)
file = File.objects.create(creator=file_creator, dataset=dataset, **file)
else:
file_creator = dataset.authors.all().first()
file = File.objects.create(creator=file_creator, dataset=dataset, **file)
dataset.save()
return dataset
</code>