Уведомления

Группа в Telegram: @pythonsu
  • Начало
  • » Django
  • » Где взять object_id для Generic Relations? Связь One-To-Many в GR? [RSS Feed]

#1 Сен. 21, 2011 08:10:02

Kotakota
От:
Зарегистрирован: 2011-06-06
Сообщения: 40
Репутация: +  0  -
Профиль   Отправить e-mail  

Где взять object_id для Generic Relations? Связь One-To-Many в GR?

Привет.
Застрял на Generic Relation.

class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True)
content_type = models.ManyToManyField(ContentType,
limit_choices_to = {'model__in': ('Editor', 'Admin','Programming')},blank=True, null=True)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
info = models.CharField(max_lenght=10)
tel = models.CharField(max_lenght=10)
class Editor(models.Model):
pass
class Admin(models.Model):
pass
class Programming(models.Model):
pass
Делаю: python manage.py syncdb
Захожу в админке в модель UserProfile, в поле “content_type”, добавляю модели с которыми будет связываться UserProfile.
А что нужно вписывать в “content_object”?
Для чего это поле? Где взять этот id?
И еще вопрос по теме.
Допустим у меня сейчас такая связь с одной из моделей:
class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True)
content_type = models.ManyToManyField(ContentType,
limit_choices_to = {'model__in': ('Editor', 'Admin','Programming')},blank=True, null=True)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
info = models.CharField(max_lenght=10)
tel = models.CharField(max_lenght=10)
class Editor(models.Model):
userprofile = models.ManyToManyKey(UserProfile)
Я могу подцепить в класс “Редакторы”, необходимое мне количество людей.
А как тоже самое провернуть с Generic Relation? Или не в этом их суть?



Офлайн

#2 Сен. 21, 2011 10:10:35

pill
От:
Зарегистрирован: 2010-08-27
Сообщения: 223
Репутация: +  0  -
Профиль   Отправить e-mail  

Где взять object_id для Generic Relations? Связь One-To-Many в GR?

В принципе тут все достаточно хорошо описано.
Основная идея использования GenericRelation - возможность иметь FK на разные модели.
content_object это атрибут который будет использоваться для доступа по FK. (если используются имена по умолчанию (content_type и object_id) - можно их не передавать в конструктор content_object)
Пример:

# Допустим ситуацию на Машинку могут устанавливаться разные модели GPS-трекеров
# Каждый трекер имеет свои уникальные особенности, потому хранить их в одной таблице сложно
# А через GenericRelations все достаточно симпатично решается
class Vehicle(models.Model):
content_type = models.ForeignKey()
# тут будет храниться id трекера
object_id = models.models.PositiveIntegerField()
# А через это поле мы будем получать к нему доступ
# Это собственно и есть content_objec
tracker = generic.GenericForeignKey()

class TrackerA(model.Model):
pass

class TrackerB(model.Model):
pass

# создаем новый Vehicle
tracker_A = TrackerA.objects.get(...)
tracker_B = TrackerB.objects.get(...)
vehicle_with_A_tracker = Vehicle.objects.create(content_type=ContentType.objects.get_for_model(tracker_A),
object_id = tracker_A.pk)
vehicle_with_B_tracker = Vehicle.objects.create(content_type=ContentType.objects.get_for_model(tracker_B),
object_id = tracker_B.pk)
...
vehicle.tracker будет возвращать либо TrakerA либо TrackerB
Теперь можно не думать о том какой именно там треккер, а просто обращаться к нему через GenericRelations.
Там есть ряд подводных камней, так что использовать наверное стоит только если иначе никак.
Kotakota
Я могу подцепить в класс “Редакторы”, необходимое мне количество людей.
А как тоже самое провернуть с Generic Relation? Или не в этом их суть?
Суть действительно не в этом.
Через танцы с бубно GenericM2Mrelations сделать можно но не думаю что нужно. Посмотреть тут можно.

Резюмируя, использовать стоит толко если четко представляешь зачем это нужно, и не выходит изменить структуру так чтобы избежать GenericRelations.

Если где-то не прав - поправьте, это скажем так ИМХО.



Офлайн

#3 Сен. 21, 2011 10:55:40

Kotakota
От:
Зарегистрирован: 2011-06-06
Сообщения: 40
Репутация: +  0  -
Профиль   Отправить e-mail  

Где взять object_id для Generic Relations? Связь One-To-Many в GR?

pill, большое спасибо!
Я думал мне это поможет в решении следующей проблемы, которая может проблемой и не является, но мне не нравится как это выглядит!
Допустим есть три модели, каждая модель это определенные части автомобиля: колеса (Wheel), шины(Bus) и рули(Handlebar).
Есть еще две модели, определяющие типы автомобилей: грузовые (Cars) и не грузовые (Cargo).
К определенным типам автомобилей, мне нужно добавлять различные колеса, шины и рули.
Вот как я это сделал:

class Cars(models.Model):
wheels = models.ManyToManyField(Wheel)
bus = models.ManyToManyField(Bus)
handlebar = models.ManyToManyField(Handlebar)
name = models.CharField(max_lenght=10)
class Cargo(models.Model):
wheels = models.ManyToManyField(Wheel)
bus = models.ManyToManyField(Bus)
handlebar = models.ManyToManyField(Handlebar)
name = models.CharField(max_lenght=10)
class Wheel(models.Model):
model = models.CharField(max_lenght=10)
class Bus(models.Model):
model = models.CharField(max_lenght=10)
class Handlebar(models.Model):
model = models.CharField(max_lenght=10)
Что мне здесь не нравится? А то что, идет повторение:
    wheels = models.ManyToManyField(Wheel)
bus = models.ManyToManyField(Bus)
handlebar = models.ManyToManyField(Handlebar)
в моделях Cars и Cargo.
А значит в БД будет две таблицы соответствия!
Так же возникает сложность выборки при таком дизайне моделей.
Я предполагал, что GenericRelation позволит мне избавится от такого типа связей.
Как можно улучшить этот вариант?



Офлайн

#4 Сен. 21, 2011 11:44:05

pill
От:
Зарегистрирован: 2010-08-27
Сообщения: 223
Репутация: +  0  -
Профиль   Отправить e-mail  

Где взять object_id для Generic Relations? Связь One-To-Many в GR?

Думаю тут лучше всего использовать наследование
https://docs.djangoproject.com/en/dev/topics/db/models/#model-inheritance

Будет что-то вроде:

class Car(models.Model):
wheels = models.ManyToManyField(Wheel)
bus = models.ManyToManyField(Bus)
handlebar = models.ManyToManyField(Handlebar)
name = models.CharField(max_lenght=10)

class Meta:
abstract = True

class Cargo(Car):
some_cargo_specific_field = models.CharField()

class Ligt(Car):
some_light_vehicle_specific_field = models.CharField()
Я честно говоря не помню как оно конкретно в SQL переводится, но работать удобно. И выглядит красиво.

ЗЫ:
Не вижу в них разницы кроме названия (или там еще что-то есть?), в таком случае не проще ли добавить поле, допустим, is_cargo и не усложнять?



Отредактировано (Сен. 21, 2011 11:47:35)

Офлайн

#5 Сен. 21, 2011 11:48:18

Kotakota
От:
Зарегистрирован: 2011-06-06
Сообщения: 40
Репутация: +  0  -
Профиль   Отправить e-mail  

Где взять object_id для Generic Relations? Связь One-To-Many в GR?

Спасибо!
Продолжаем изучать!



Офлайн

  • Начало
  • » Django
  • » Где взять object_id для Generic Relations? Связь One-To-Many в GR?[RSS Feed]

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version