Jan. 24, 2020, 9:52 a.m.

Как лучше реализовать модели в бд?

database, Django

Здравствуйте. Снова я здесь со своими вопросами)
Как лучше реализовать структуру моделей для файлов?
Хочу хранить файлы в отдельной модели или моделях (это уже как вы мне подскажите).
Ну так вот, какая схема лучше подойдёт?
1. Делать несколько моделей, которые имеют отношения OneToOne с моделью File.
2. Или же одну модель File, где будет поле file_type.

Мне чутьё подсказывает, что 1-ый вариант лучше использовать, если пригодятся какие-то дополнительные поля для каждого типа файла, а во всех остальных 2-ой.

1.

class File(models.Model):
    pass

class AbstractFile(models.Model):
    filename = models.FileField(upload_to='files')
    file = models.OneToOneField(File, on_delete=models.CASCADE, primary_key=True)
    date = models.DateTimeField(auto_now_add=True, null=True, blank=True)

    class Meta:
        abstract = True

    def delete(self, *args, **kwargs):
        self.file.delete()
        return super(self.__class__, self).delete(*args, **kwargs)

class Image(AbstractFile):
    filename = models.ImageField(upload_to='images')

class Document(AbstractFile):
    pass

2.

class File(models.Model):
    DOCUMENT = 0
    IMAGE = 1
    AUDIO = 2
    VIDEO = 3

    FILE_TYPE_CHOICES = (
        (DOCUMENT, 'Документ'),
        (IMAGE, 'Изображение'),
        (AUDIO, 'Видео'),
        (VIDEO, 'Аудио')
    )
    file_type = models.PositiveSmallIntegerField(choices=FILE_TYPE_CHOICES, default=DOCUMENT)
    file = models.FileField(upload_to='files')

И ещё... Как можно сделать, чтобы в 1-ом варианте можно было к File связать только с одним объектом. Допустим два объекта Image я не могу связать через OneToOne с File, это понятно, но можно 1 Image и 1 Document. Как сделать, чтобы можно было связать только с одной либо Image, либо Document...?

We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.
6

я думаю, правильнее всего начать с того, какую задачу вы пытаетесь решить.
по большому счету imageField отличается от FileField только проверками, что в поле приехала именно картинка

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

я думаю, если это вдруг отвечает вашим хотелкам, вы можете сделать 2 разные формы для этого, в одной из которых сделать поле ImageField (со всеми вытекающими проверками), а в другой оставить FileField. Но в обоих случаях все складывать в одну модель с типом поля FileField.
Но в любом случае, не зная предметную область, очень сложно дать какой-то вменяемый ответ. Лучше всего всегда начинать с описания, что вы хотите сделать - так будет проще=)

кстати, из интересного - не обязательно указывать OneToOne на модель=)

class File(models.Model):
    pass

class ImageFile(File): # тут будет связь один к одному на модель File
    pass

class AbstractFile(models.Model):
    class Meta:
        abstract = True

class ImageFileInheritance(AbstractFile): # а тут будет уже наследование
    pass

если хотите наследоваться - надо указать в File.Meta.abstract = True

Хорошо. Вот подробности)
Делаю бота в telegram. Telegram каждому файлу загружаемому на их сервера даёт некий file_id. Мне нужно записывать это file_id в бд. И следующий раз не файл отправлять пользователю, а этот file_id.

Сейчас у меня есть модель Image. И есть FileID, которая хранит file_id каждой картинки.
Также у меня есть модель TelegramBot, так как ботов целых 2 штуки. Связи с этим в модель FileID добилось поле bot, которая хранит ссылку на бота. Так сделано потому что у одного файла может быть разный file_id, в зависимости от того в какой бот был загружен файл.

Вот модель FileID для наглядности

class FileID(models.Model):
    name = models.CharField(max_length=100)
    image = models.ForeignKey(Image, on_delete=models.CASCADE, related_name='file_ids')
    bot = models.ForeignKey(TelegramBot, on_delete=models.CASCADE, related_name='file_ids')

    def __str__(self):
        return self.name

В поле name хранится тот самый file_id.

Всё это время я работал только с картинками, но теперь нужно добавить и другие файлы.
Поэтому решил сделать отдельную модель File, ссылку на которую добавлю в FileID вместо Image.

Ещё появилась мысля сделать, отдельно модели Image, Document, Video, Audio. А в FileID использовать GenericForeignKey.
Или сделать так:

class File(models.Model):
    image = ForeignKey(Image, null=True, blank=True)
    video = ForeignKey(Video, null=True, blank=True)
    audio = ForeignKey(Audio, null=True, blank=True)
    document = ForeignKey(Document, null=True, blank=True)

А при сохранении разрешить только один тип файла.

Я уже, честно говоря, запутался.

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

Comments

Only authorized users can post comments.
Please, Log in or Sign up
Donate

Hello, Dear Users of EVILEG!!!

If the site helped you, then support the development of the site financially, please.

You can do it by following ways:

Thank you, Evgenii Legotckoi

M
Feb. 26, 2020, 9:48 p.m.
Metalhaker

C++ - Test 001. The first program and data types

  • Result:60points,
  • Rating points-1
a
Feb. 25, 2020, 5:40 a.m.
ayb

C++ - Test 005. Structures and Classes

  • Result:83points,
  • Rating points4
DZ
Feb. 24, 2020, 2:47 p.m.
Dmitrij Zlobin

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:40points,
  • Rating points-8
Last comments
Feb. 24, 2020, 3:54 a.m.
Evgenij Legotskoj

Добрый день. Там будет url, на который указывает ссылка тега a в пагинаторе, если правильно помню )) Написал этот код и забыл.
B
Feb. 24, 2020, 12:37 a.m.
BahaMeirman

Евгений Здравствуйте! Не могу понять вот эту часть кода: url: jQuery(this).attr('action') наверное здесь должен быть путь к url, тогда 'action' на какой url указывает?
Feb. 17, 2020, 3:22 a.m.
Evgenij Legotskoj

Добрый день. Это кастомный тег, помещается в файл, который находится в каталоге templatetags myapp/ templatetags/ myapp.py
B
Feb. 16, 2020, 1:36 p.m.
BahaMeirman

Добрый вечер! Монжно по подробней о теге get_companion? ссылка не работает.
Now discuss on the forum
v
Feb. 26, 2020, 6:13 p.m.
vlaaad20

Добавил в папку проекта следующие либы, ничего не изменилось. Надо что-то где-то дополнительно прописывать или нет? Я просто не очень понимаю...
a
Feb. 25, 2020, 8:06 a.m.
ayb

Да
Feb. 24, 2020, 12:04 p.m.
Evgenij Legotskoj

Добрый день. Вот пример с дружественного ресурса с движением камеры
Feb. 24, 2020, 6:29 a.m.
Evgenij Legotskoj

Qt не предоставляет функционала по запросу root прав во время выполнения программы. Поэтому нужно использовать платформозависимый функционал, для Linux это будет выглядеть так: #include…
Feb. 24, 2020, 3:47 a.m.
Evgenij Legotskoj

Добрый день. Что означает клиентская область? Это изображение? Вам нужно распознавать символы текста или всё-таки пользователь будет вводить текст с клавиатуры, просто в любом месте "абстр…
EVILEG
About
Services
© EVILEG 2015-2019
Recommend hosting TIMEWEB