Лучший способ представить отношения многие ко многим в django admin - PullRequest
5 голосов
/ 25 февраля 2010

У меня есть уникальная проблема в том, как она должна обрабатываться в администраторе django.

У меня следующая структура моделей ...

class Product(models.Model):
    name    = models.CharField(max_length = 100)
    base_price = models.DecimalField(max_digits = 5, decimal_places = 2)


    def __unicode__(self):
        return self.name


class Country(models.Model):
    name = models.CharField(max_length = 2)
    base_price = models.DecimalField(max_digits = 5, decimal_places = 2)    

    def __unicode__(self):
        return self.name


class CountryProduct(models.Model):
    country = models.ForeignKey(Country)
    product = models.ForeignKey(Product)
    overriden_price = models.DecimalField(max_digits = 5, decimal_places = 2)

    class Meta:
        unique_together = (("country", "product"),)

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

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

countries -> | US  | UK 
products     |     |
---------------------------
Product1     |  -  |  10
Product2     |  5  |   7

Но я не знаюкак это сделать ....

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

Заранее спасибо:)

Ответы [ 3 ]

2 голосов
/ 26 февраля 2010

У меня есть решение, вот мой ответ на мой вопрос ... Позвольте мне поделиться им с вами ... Я изменил модель следующим образом ....

class Product(models.Model):
    name    = models.CharField(max_length = 100)
    base_price = models.DecimalField(max_digits = 5, decimal_places = 2)


    def __unicode__(self):
        return self.name


class Country(models.Model):
    name = models.CharField(max_length = 2)
    base_price = models.DecimalField(max_digits = 5, decimal_places = 2)    
    products = models.ManyToManyField(Product, through = 'CountryProduct')

    def __unicode__(self):
        return self.name


class CountryProduct(models.Model):
    country = models.ForeignKey(Country)
    product = models.ForeignKey(Product)
    overriden_price = models.DecimalField(max_digits = 5, decimal_places = 2)

    class Meta:
        unique_together = (("country", "product"),)


class CountryProductInline(admin.TabularInline):
    model = CountryProduct

class CountryAdmin(admin.ModelAdmin):
    inlines = [CountryProductInline]

class ProductAdmin(admin.ModelAdmin):
    inlines = [CountryProductInline]

Хотя это не то, что я ожидал, это дает мне еще лучшее решение ...

0 голосов
/ 25 февраля 2010

Это - потенциально - ужасный дизайн. Ваша таблица базы данных должна содержать правильную цену.

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

Вы не можете просто заставить SQL работать с тем типом сетки, который вы показываете.

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

Для создания сетки вы должны выбрать все ваши страны и продукты. Затем вы должны создать соответствующий список списков. Затем вы можете написать свой собственный шаблон для отображения этого. После того, как у вас будет более 12 стран, сетка станет настолько широкой, что станет практически бесполезной. Но для первых нескольких стран вы можете сделать эту работу.

Для этого вам нужно создать собственный шаблон и собственную функцию просмотра.

Редактировать

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

Какое требование? Бедный дизайн, где требуется два запроса, чтобы найти цену? Это требуется?

Или очень сложная сетка? Это требуется?

Не ясно, что такое "требование", поэтому невозможно предложить какую-либо альтернативу. Можно только сказать

  1. Конструкция SQL, которая запрашивает базовые и переопределения отдельно, будет медленнее и сложнее.

  2. Проект SQL, который имеет единственное значение, которое загружается из «динамического значения по умолчанию» и может быть изменен (или нет) пользователем, намного, намного проще. Это можно сделать с помощью аргумента initial. http://docs.djangoproject.com/en/dev/ref/forms/fields/#initial

  3. SQL не может легко превратить несколько строк в решетчатую структуру. Для этого требуется либо сложный SQL (далеко за пределами возможностей ORM), либо обработка Python в функции представления.

  4. Администратор Django вообще не будет создавать сетчатые структуры.

0 голосов
/ 25 февраля 2010

У администратора django нет способа сделать то, что вам нужно.

Вы можете создать свой собственный вид и сделать это таким образом. Вы можете добавить дополнительные представления в класс admin.ModelAdmin, который будет делать то, что вам нужно.

...