Django отображает значение дополнительного поля в форме модели - PullRequest
3 голосов
/ 16 декабря 2009

Как установить значение поля (которое имеет отношение к форме, но не основано непосредственно на той же модели) в форме (модели), когда оно отображается в админке?

Вот упрощенная версия того, что у меня есть (мое настоящее приложение / модель / и т. Д. Более сложное):

  • A building имеет много room s
  • A room имеет много частей equipment

Модель:

#spaces/models.py
from django.db import models    

class Building(models.Model):
    name=models.CharField(max_length=32)
    def __unicode__(self):
      return self.name

class Room(models.Model):
    number=models.CharField(max_length=8)
    building=models.ForeignKey(Building)
    def __unicode__(self):
        return self.number

class Equipment(models.Model):
    tech = models.CharField(max_length=64)
    room = models.ForeignKey(Room)
    def __unicode__(self):
     return self.tech

При добавлении или редактировании части оборудования было бы неплохо иметь возможность ограничить выбор room (построением). Это я могу сделать: я добавляю поле building в ModelForm, а затем, когда пользователь изменяет его, бит JQuery в файле шаблона динамически обновляет список room s. admin.py часть выглядит так:

#spaces/admin.py
from demo.spaces.models import Building, Room, Equipment
from django.contrib import admin
from django import forms


class EquipmentForm(forms.ModelForm):
     class Meta:
      model = Equipment
     building = forms.ModelChoiceField(Building.objects)

class EquipmentAdmin(admin.ModelAdmin):
     form = EquipmentForm

admin.site.register(Equipment, EquipmentAdmin)
admin.site.register(Building)
admin.site.register(Room)

При добавлении нового фрагмента equipment все это работает нормально - мой код JQuery отображает ----- до тех пор, пока не будет выбрано здание, после чего раскрывающийся список для поля room будет включен и заполнен кнопкой соответствующие room s для этого здания.

Проблема: при отображении существующего элемента оборудования (demo.com/admin/spaces/equipment/12/) или если форма добавления не проверяется, поле Room правильно отображает room - но building поле уничтожено. В экземпляре формы существует значение внешнего ключа equipment.room, и администратор автоматически устанавливает для этого поля значение room, но я должен установить значение поля building.

Я могу получить значение без проблем, поскольку в init формы легко проверить, является ли он экземпляром, а затем вернуться обратно, чтобы получить значение:

def __init__(self, *args, **kwargs):  
     super(EquipmentForm, self).__init__(*args, **kwargs)  
     if 'instance' in kwargs:
        building_value = kwargs['instance'].room.building

Но что мне делать с этим значением, чтобы поле отображало его? Единственное, что я еще не пробовал, это добавить больше кода в мой шаблон, чтобы использовать Jquery для получения значения и установки его в конце, но я бы предпочел, чтобы JavaScript на странице не попадал в базу данных для отображения рисунков. значение, так как кажется, что это должно быть сделано при визуализации формы ...

Есть мысли? Спасибо за помощь!

Ответы [ 4 ]

1 голос
/ 15 января 2014

Это должно работать:

class EquipmentForm(ModelForm):
    def __init__(self, *args, **kwargs):
        kwargs['initial']=kwargs.get('initial',{})
        if kwargs['instance']:
            kwargs['initial']['building']=kwargs['instance'].building
        super(EquipmentForm, self).__init__(*args, **kwargs)  

В views.py:

instance.building="some_building"
form = EquipmentForm(request.POST, instance=instance)
1 голос
/ 16 декабря 2009

Проверьте параметр initial для Field в формах здесь . Возможно, поможет установка здания с начальным значением объекта Building.


Кроме того, вам действительно нужно ограничить выбор зданиями? Я только что нашел достаточно, чтобы изменить метод Room __unicode__, чтобы он показывал Building и Room число:

def __unicode__(self):
    return "Room nr %s in %s" % (self.number, self.building)

Тогда вы получите список всех комнат, но легко узнать, к какому зданию они относятся ...

0 голосов
/ 14 января 2010

Это работает для меня:

def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None,
                 initial=None, error_class=ErrorList, label_suffix=':',
                 empty_permitted=False, instance=None):
        if instance:
            initial = initial or {}
            initial['field_name'] = instance.some_value

        super(MyCustomForm, self).__init__(data, files, auto_id, prefix,initial,
                error_class, label_suffix,empty_permitted, instance)

Я намеренно не использую * args, ** kwargs, потому что я не проверял, как этот конструктор называется elswere в коде (экземпляр и initial могут быть в * args или ** kwargs).

0 голосов
/ 16 декабря 2009

Как насчет этого?

def __init__(self, *args, **kwargs):  
 super(EquipmentForm, self).__init__(*args, **kwargs)  
 if 'instance' in kwargs:
    self.data['building']=kwargs['instance'].room.building
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...