Django maps an optional field value to modelform

How to set the value of a field (which refers to the form, but is not based directly on the same model) in the form (model) when it is displayed in the admin panel?

Here is a simplified version of what I have (my actual application / model / etc is more complex):

  • A buildinghas many rooms
  • A roomhas many partsequipment

Models:

#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

When adding or editing a piece of equipment, it would be nice to limit the selection to roomempty (by building). I can do this: I add a field buildingto ModelForm, and then when the user receives it, a little jQuery in the template file dynamically updates the list rooms. The item is admin.pyas follows:

#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 .

: (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 , , , ...

? !

+3
4

initial Field . , Building .


, ? , Room __unicode__, Building, Room :

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

, , ...

+1

:

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

?

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

:

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

Source: https://habr.com/ru/post/1725802/


All Articles