I need a way to modify one ModelAdmin member variable from another ModelAdmin. So I though maybe I could use a global variable. However, if there where multiple users using the app at the same time, then the global variable would keep on getting changed unexpectedly and all hell would break loose.
Is there any method in Django would allow me to modify one ModelAdmin member variable from another ModelAdmin?
Or am I making a design mistake? Am I making this harder than it really is or am I missing something? What about using threading and locks? Message passing??? Events?!?!?! HELP
Here's the whole story. My app lets it's users build a PC by choosing compatible CPU, motherboard, memory, and hard drives (in that order). By choosing a cpu, they're limited to motherboards with the CPU's socket. By choosing a motherboard with DDR3 dimms, they're limited to DDR3 memory, and so on.
Also, sense there can be many of the same parts per system (example: memory modules, but they must be identical), I had to create ManyToManyField relationships and specify the intermediary table (with an extra count
field) with the through
arg. This requires that InlineAdmin models be used to display the fields in the admin page.
To my delight, the raw_id_field variable caused the dropdown widget to be replaced with a button that pops up a form identical to change_list.html and allows users to filter/sort/search for the part they want. However, this was not good enough for my boss. Now I need those filters to be predefined according to earlier selections (i.e. filter for Memory with DDR3 after selecting a motherboard with DDR3). So I implimented this: Default filter in Django admin but I need a way to set the CpuAdmin.default_filters
from the PcAdmin
dynamically based on what other choices they made.
My models, only including one part model for brevity:
# models.py
class CPU(Part):
partNum = models.CharField(max_length=60)
price = models.DecimalField(precision=2)
socket = models.CharField(max_length=60)
numCores = models.CharField(max_length=60)
class PC(models.Model):
name = models.CharField(max_length=60)
customer = models.CharField(max_length=60)
cpuChoices = models.ManyToManyField(CPU, through='PcCpuChoice')
memoryChoices = models.ManyToManyField(Memory, through='PcMemoryChoice')
hardDriveChoices = models.ManyToManyField(HardDrive, through='PcHardDriveChoice')
motherBoardChoices = models.ManyToManyField(MotherBoard, through='PcMotherboardChoice')
class PcCpuChoice(models.Model):
pc = models.ForeignKey(PC, unique=False)
cpu = models.ForeignKey(CPU, unique=False)
count = models.IntegerField()
# admin.py
class PartAdmin(admin.ModelAdmin):
class Meta:
abstract = True
search_fields = ['partNum', 'description', 'model']
default_filter = []
def changelist_view(self, request, extra_context=None):
if not request.GET.has_key(self.default_filter[0]):
q = request.GET.copy()
q[self.default_filter[0]] = self.default_filter[1]
request.GET = q
request.META['QUERY_STRING'] = request.GET.urlencode()
return super(PartAdmin,self).changelist_view(request, extra_context=extra_context)
class CpuAdmin(PartAdmin):
list_filter = ['brand', 'socket', 'numCores', 'graphics']
list_display = ('partNum', 'description', 'brand', 'model', 'markupPrice', 'clockSpeed', 'watts', 'voltage')
default_filter = ['numCores','8'] # need to change this from PcAdmin!!!
class PcCpuInline(admin.TabularInline):
model = PcCpuChoice
extra = 1
max_num = 1
raw_id_fields = ['cpu']
class PcAdmin(admin.ModelAdmin):
inlines = [PcCpuInline, PcMotherboardInline, PcMemoryInline, PcHardDriveInline]
admin.site.register(PC, PcAdmin)