как настроить значения формы в django admin, чтобы показывать только те значения, которые ему присвоены? - PullRequest
1 голос
/ 25 февраля 2011

Я реализовал разрешение на уровне строк в моем приложении администратора django. У меня есть три модели:

  1. Курс - {Название, код}

  2. Единица - {Заголовок, Курс (внешний ключ)}

  3. Тема - {Заголовок, Единица (внешний ключ)}

Примечание: (слова, выделенные жирным шрифтом, являются названиями моделей, а значения в фигурных скобках - полями для каждой модели)

Каждый пользователь имеет право добавлять / редактировать / удалять определенные курсы, которые ему назначены. Я использую метод def queryset(self, request):, чтобы проверить, у какого пользователя есть разрешение на какие курсы, а затем вернуть набор запросов с этими курсами. Таким образом, я могу отображать определенные курсы пользователя, назначенные ему / ей.

A курс может иметь много юнитов, и далее юнит может иметь много тем. Это иерархия.

Так что я снова использую тот же def queryset(self, request): для фильтрации Юнитов и Тем, чтобы показать только те Единицы и Темы, которые входят в курс, назначенные ему / ей. До сих пор все идет хорошо, так как пользователь может видеть только те Единицы и тем , которые связаны с его / ее курсом . Но когда пользователь пытается редактировать единицу, появляется форма с двумя полями:

  1. Заголовок (название единицы, которую он может переименовать)
  2. курс (выпадающий список всех курсов, из которых он может выбрать любой / внешний ключ)

Во втором поле раскрывающийся список "курс" Я просто хочу, чтобы пользователь мог видеть только те курсы, которые ему назначены. Поэтому он / она не сможет обновлять Подразделение с любым другим курсом, который ему не назначен.

Тот же случай, что и при редактировании Темы , пользователь может видеть все Единицы в раскрывающемся поле и может выбрать любую единицу для темы.

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

Ответы [ 2 ]

1 голос
/ 03 июля 2015

Вы можете использовать django-smart-select

from smart_selects.db_fields import ChainedForeignKey

пример кода

from django.db import models
from smart_selects.db_fields import ChainedForeignKey

class Continent(models.Model):
    name = models.CharField(max_length=100)
    def __unicode__(self):
        return self.name

class Country(models.Model):
    name=models.CharField(max_length=100)
    continent=models.ForeignKey(Continent)
    def __unicode__(self):
        return self.name

class Area(models.Model):
    name=models.CharField(max_length=100)
    country=models.ForeignKey(Country)
    def __unicode__(self):
        return self.name

class Location(models.Model):
    continent = models.ForeignKey(Continent)
    country = ChainedForeignKey(
        Country, 
        chained_field="continent",
        chained_model_field="continent", 
        show_all=False, 
        auto_choose=True
    )
    area = ChainedForeignKey(Area, chained_field="country", chained_model_field="country")
    city = models.CharField(max_length=50)
    street = models.CharField(max_length=100)

    def get_products(self):
        return ','.join([p.name for p in self.area.all()])
1 голос
/ 26 февраля 2011

Вам, вероятно, следует переопределить метод formfield_for_foreignkey в вашем ModelAdmin для Unit, чтобы изменить набор запросов на основе запроса.Что-то вроде (не проверено):

class UnitAdmin(admin.ModelAdmin):
    def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
        if db_field.name == 'course':
            # filter queryset somehow based on request.user:
            kwargs['queryset'] = db_field.rel.to._default_manager.filter(...) 
        return super(
            UnitAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
...