Найти - Пользователи
Полная версия: ForeignKey и 2 модели
Начало » Django » ForeignKey и 2 модели
1 2
empirik
Мне нужно связать поле модели с двумя другими моделями через ForeignKey, одна из них - моя, другая - стандартная джанговая User. Так уж получилось, что нужно в админке из одного открывающегося списка выбирать переменную либо из одной модели, либо из другой.
Мне посоветовали посмотреть на GegericRelations, но, насколько я понял, там нужно создавать еще одну модель и, соответственно, создавать переменные ее типа. Но тогда же нужно будет каждый раз, когда в систему будет добавляться новый пользователь или переменная другой модели, создавать еще одну переменную нового типа. Или я чего-то недопонимаю?
FishHook
Покажите модели, а то так весьма трудно понять, что же Вам нужно.
empirik
У меня есть модель Circuit. Она описывает некоторое устройство. Есть модель стандартная модель джанги User и еще одна моя модель, которая описывает некоторые места на складе. Мне нужно, чтобы в админке из одного раскрывающегося списка я смог выбрать либо одного из пользователей, у которого хранится данное конкретное устройство, либо это самое место на складе из списка.
Думаю, приводить код моделей здесь особого смысла нет, их внутренняя организация не имеет значения в данном случае.
FishHook
Имя, сестра, имя.
Код, брат, код!
empirik
from django.contrib.auth.models import User
class Circuit(models.Model):
    circuit_id = models.PositiveIntegerField(verbose_name=_("Circuit ID"), blank=True, null=True)
    model = models.ForeignKey(Versiiplates, verbose_name=_("Model"))
    date_created = models.DateField(blank=True, null=True, verbose_name=_("Date Created"), default=datetime.date.today())
    manufacturer = models.ForeignKey(Manufacturer, null=True, blank=True, verbose_name="Производитель")
    manufacturer_comments = models.TextField(max_length=2500, null=True, blank=True, verbose_name="Комментарии производителя")
    keeper = models.ForeignKey(User, null=True, blank=True, verbose_name="Хранится")
    status = models.PositiveIntegerField(verbose_name=_("Status"), choices=STATUS_TYPE, default=0)
    status_history = models.ManyToManyField(Status, blank=True, null=True)
    status_comment = models.TextField(max_length=2500, blank=True, null=True, verbose_name="Комментарий")
    def __unicode__(self):
        return u"%s #%d" % (self.model, self.circuit_id)
    class Meta:
        verbose_name = _("Circuit")
        verbose_name_plural = _("Circuits")
class StoreCell(models.Model):
    def __unicode__(self):
        return u'Cell #%d' % self.pk
Ну вот как-то так. Как видно из кода, поле keeper ссылается только на пользователя, а мне нужно, чтобы я мог выбрать либо пользователя, либо объект типа StoreCell в админке из списка раскрывающегося.
FishHook
class StoreCell(models.Model):
    def __unicode__(self):
        return u'Cell #%d' % self.pk
Странная модель, может я чего то не понимаю в Джанге, но как это будет представлено в БД? Если никак, то какой “объект типа StoreCell” вы хотите получить, и что должно быть в “списке раскрывающегося” для этого объекта?
empirik
Ну, в списке просто Cell и ключ объекта, как и указано в методе __unicode__(). Там ничего и не должно в модели еще быть, кроме как одно лишь число, указывающее номер ячейки. Это не имеет принципиальной важности, интересно другое: как можно связать поле модели Circuit сразу с двумя разными моделями. Причем одна из них ведь стандартная от джанги. А значит, не получится создать некую базовую модель, вроде StoreItem, от которой можно было бы наследовать две другие.
inoks
empirik
Мне посоветовали посмотреть на GegericRelations, но, насколько я понял, там нужно создавать еще одну модель и, соответственно, создавать переменные ее типа.

Эта модель django.contrib.contenttypes.models.ContentType по умолчанию включена для всех приложений на джанго.

Вот пример оттуда же для назначения метки произвольному объекту из моделей приложения:

from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic
class TaggedItem(models.Model):
    tag = models.SlugField()
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')
    def __unicode__(self):
        return self.tag
FishHook
Зачем Вам модель, которая не содержит ни одного поля? Когда Вы ответите на этот вопрос мне, а может и себе, уверен что вопрос исчезнет сам собой. Есть отношения один-к-одному, многие-ко-многим, есть ссылки на ключ, чего Вы хотите я не понимаю.
Может быть начнем с начала?
Давайте попробуем построить схему данных, опишите задачу.
empirik
inoks
Эта модель django.contrib.contenttypes.models.ContentType по умолчанию включена для всех приложений на джанго.
Да, я уже видел это.
>>> from django.contrib.auth.models import User
>>> guido = User.objects.get(username='Guido')
>>> t = TaggedItem(content_object=guido, tag='bdfl')
>>> t.save()
>>> t.content_object
<User: Guido>
Здесь получается, что нужно каждый раз создавать объект этого типа TaggedItem. Получается, мне нужно где-то в коде следить за тем, не создался ли у меня объект одного из типов User или StoreCell и тогда добавлять объект типа TaggedItem. Со StoreCell все просто, это мой объект, можно, к примеру добавить код в save_model в admin.py. А как быть с классом User?
FishHook
Зачем Вам модель, которая не содержит ни одного поля? Когда Вы ответите на этот вопрос мне, а может и себе, уверен что вопрос исчезнет сам собой. Есть отношения один-к-одному, многие-ко-многим, есть ссылки на ключ, чего Вы хотите я не понимаю. Может быть начнем с начала? Давайте попробуем построить схему данных, опишите задачу.
Пусть в модели StoreCell будет поле PositiveIntegerField, которое характеризует номер ячейки на складе. Вообще это не обязательно, если использовать стандартный джанговский ключ. Он итак при создании нового объекта будет инкрементироваться. А зачем создавать модель, в которой ничего больше нет? А потому что я вот уверен, что потом понадобится добавлять что-то еще. А добавить пару полей и мигрировать схему через south будет проще.
ЗАДАЧА: Через ForeignKey ссылаться не на одну модель, а на две. Логично, что нужен какой-то промежуточный класс, который объединял бы эти две модели, ведь по факту-то на обе через связь Один ко многим обращаться невозможно.
Как это выглядит: Пользователь открывает в админке страничку некоторого объекта Circuit и видит: Он у пользователя Васи или в такой-то ячейке на складе.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB