Как я ограничиваю выбор внешних ключей связанными объектами только в django

Означает ли это, что миндаль не поддерживает внешние скрипты?

blockquote>

Да, это именно то, что это значит. Из раздела «Ограничения» , очень первый элемент:

оптимизирует все модули в один файл - без загрузки динамического кода.

blockquote>

(Акцент добавлен.)

51
задан Jeff Mc 24 October 2008 в 03:52
поделиться

5 ответов

Я просто столкнулся ForeignKey.limit_choices_to в документах Django. Не уверенный все же, как это работает, но это могла бы просто быть правильная вещь здесь.

Обновление: ForeignKey.limit_choices_to позволяет определять или константу, вызываемое или объект Q ограничить допустимый выбор для ключа. Константа, очевидно, бесполезна здесь, так как она ничего не знает о включенных объектах.

Используя вызываемое (функциональный или метод класса или любой вызываемый объект) кажется более многообещающим. Однако проблема того, как получить доступ к необходимой информации от объекта HttpRequest, остается. Используя локальная память потока может быть решением.

2. Обновление: Вот то, что работало на меня:

я создал промежуточное программное обеспечение, как описано в ссылке выше. Это извлекает один или несколько аргументов от запроса, ПОЛУЧАЮТ часть, такую как "product=1", и хранит эту информацию в местных жителях потока.

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

@classmethod
def _product_list(cls):
    """
    return a list containing the one product_id contained in the request URL,
    or a query containing all valid product_ids if not id present in URL

    used to limit the choice of foreign key object to those related to the current product
    """
    id = threadlocals.get_current_product()
    if id is not None:
        return [id]
    else:
        return Product.objects.all().values('pk').query

важно возвратить запрос, содержащий все возможные идентификаторы, если ни один не был выбран так, чтобы нормальные администраторские страницы работали хорошо.

поле внешнего ключа тогда объявляется как:

product = models.ForeignKey(
    Product,
    limit_choices_to={
        id__in=BaseModel._product_list,
    },
)

выгода - то, что необходимо предоставить информацию для ограничения выбора через запрос. Я не вижу способ получить доступ "сам" здесь.

32
ответ дан Dan Swain 7 November 2019 в 20:04
поделиться

Я пытаюсь сделать что-то подобное. Похоже, все, кто говорит «у вас должен быть только один внешний ключ», возможно, неправильно поняли, что вы пытаетесь сделать.

Жаль, что limit_choices_to = {"myparent": "self"}, который вы хотели сделать, не делает " т работать ... это было бы чисто и просто. К сожалению, «self» не оценивается и передается как простая строка.

Я подумал, что смогу сделать:

class MyModel(models.Model):
    def _get_self_pk(self):
        return self.pk
    favourite = models.ForeignKey(limit_choices_to={'myparent__pk':_get_self_pk})

Но, увы, это выдает ошибку, потому что функции не передается аргумент self :(

Похоже, что единственный способ - поместить логику во все формы, использующие эту модель (т.е. передать набор запросов в варианты выбора для вашего поля формы). Это легко сделать, но было бы более СУХИМ иметь это на модельном уровне. Переопределение метода сохранения модели кажется хорошим способом предотвратить получение неверных вариантов.

Обновление
Другой способ см. В моем последующем ответе https://stackoverflow.com/a/3753916/202168

2
ответ дан 7 November 2019 в 10:04
поделиться

Вы хотите ограничить выбор, доступный в администраторском интерфейсе при создании/редактировании образцового экземпляра?

Один способ сделать это - проверка модели. Это позволяет Вам повысить ошибку в администраторском интерфейсе, если внешнее поле не является правильным выбором.

, Конечно, ответ Eric корректен: Вам только действительно нужен один внешний ключ от ребенка для порождения здесь.

3
ответ дан Ber 7 November 2019 в 20:04
поделиться

@Ber: Я добавил проверку к модели, подобной этому

class Parent(models.Model):
  name = models.CharField(max_length=255)
  favoritechild = models.ForeignKey("Child", blank=True, null=True)
  def save(self, force_insert=False, force_update=False):
    if self.favoritechild is not None and self.favoritechild.myparent.id != self.id:
      raise Exception("You must select one of your own children as your favorite")
    super(Parent, self).save(force_insert, force_update)

, который работает точно, как я хочу, но было бы действительно хорошо, если эта проверка могла бы ограничить выбор в выпадающем в администраторском интерфейсе вместо того, чтобы проверить после выбора.

3
ответ дан Jeff Mc 7 November 2019 в 20:04
поделиться

Это не то, как django работает. Вы только создали бы отношение, идущее одним путем.

class Parent(models.Model):
  name = models.CharField(max_length=255)

class Child(models.Model):
  name = models.CharField(max_length=255)
  myparent = models.ForeignKey(Parent)

И если бы Вы пытались получить доступ к детям от родителя, Вы сделали бы parent_object.child_set.all(). Если бы Вы устанавливаете related_name в myparent поле, то, именно это Вы отослали бы к нему как. Исключая: related_name='children', тогда Вы сделали бы parent_object.children.all()

Read эти документы http://docs.djangoproject.com/en/dev/topics/db/models/#many-to-one-relationships для больше.

12
ответ дан S.Lott 7 November 2019 в 20:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: