Add a dynamic number of fields to Django admin form
I have 3 models "Configuration", "Process", and "ProcessConfiguration" as defined below:
class Configuration(models.Model):
name = models.CharField(max_length=MAX_CONFIGURATION_NAME_LEN,
unique=True, db_index=True)
description = models.TextField(blank=True)
validation = models.CharField(max_length=MAX_CONFIGURATION_VALIDATION_LEN,
blank=True)
entity = models.CharField(max_length=MAX_CONFIGURATION_ENTITY_LEN,
blank=False)
is_customer_visible = models.BooleanField(default=False, editable=True)
class ProcessConfiguration(models.Model):
process = models.ForeignKey(Process, on_delete=models.CASCADE, db_index=True)
configuration = models.ForeignKey(Configuration, on_delete=models.CASCADE, db_index=True)
value = models.TextField()
created = models.DateTimeField(editable=False, auto_now_add=True, db_index=True)
def __str__(self):
return self.process.name + ": " + self.configuration.name + " = " + self.value[:80]
class Meta:
unique_together = ('process', 'configuration')
class Process(models.Model):
name = models.CharField(max_length=MAX_PROCESS_NAME_LEN)
What I am trying to do is to add a new CharFeild to the Process admin form for each of the Configuration objects that have a particular entity flag set.
I thought I would be able to do this in a similar way to how I have added other fields to forms, but within a loop.
class ProcessCreateForm(forms.ModelForm):
test_above = forms.CharField()
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
extented_configurations =
Configuration.objects.filter(entity='proc',
is_customer_visible=True)
for config_item in extented_configurations:
kwargs = {
'label': "123",
'required': False
}
field_class = forms.CharField
self.fields[config_item.name] = field_class(**kwargs)
When I print out the fields at the end of the init, I can see that the new fields have been added, however when I load the page I can only see the "test_above" field.
In my admin.py module I have registered the model to an admin class that I have created in another module:
from X.models import Process
from X.model_admins import ProcessAdmin
admin.site.register(Process, ProcessAdmin)
Here is the ProcessAdmin snippet model_admin module:
class ProcessAdmin(admin.ModelAdmin):
list_display = ['name']
def get_form(self, request, obj=None, **kwargs):
from X.admin_forms import ProcessCreateForm
defaults = {}
defaults['form'] = ProcessCreateForm
defaults.update(kwargs)
return super().get_form(request, obj, **defaults)
The end goal of this is when an admin user is adding a new process, then they should be able to add new 'ProcessConfiguration' that are associated with the model that they are creating.
Is this the right way to approach this issue?
python django python-3.x django-models django-forms
add a comment |
I have 3 models "Configuration", "Process", and "ProcessConfiguration" as defined below:
class Configuration(models.Model):
name = models.CharField(max_length=MAX_CONFIGURATION_NAME_LEN,
unique=True, db_index=True)
description = models.TextField(blank=True)
validation = models.CharField(max_length=MAX_CONFIGURATION_VALIDATION_LEN,
blank=True)
entity = models.CharField(max_length=MAX_CONFIGURATION_ENTITY_LEN,
blank=False)
is_customer_visible = models.BooleanField(default=False, editable=True)
class ProcessConfiguration(models.Model):
process = models.ForeignKey(Process, on_delete=models.CASCADE, db_index=True)
configuration = models.ForeignKey(Configuration, on_delete=models.CASCADE, db_index=True)
value = models.TextField()
created = models.DateTimeField(editable=False, auto_now_add=True, db_index=True)
def __str__(self):
return self.process.name + ": " + self.configuration.name + " = " + self.value[:80]
class Meta:
unique_together = ('process', 'configuration')
class Process(models.Model):
name = models.CharField(max_length=MAX_PROCESS_NAME_LEN)
What I am trying to do is to add a new CharFeild to the Process admin form for each of the Configuration objects that have a particular entity flag set.
I thought I would be able to do this in a similar way to how I have added other fields to forms, but within a loop.
class ProcessCreateForm(forms.ModelForm):
test_above = forms.CharField()
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
extented_configurations =
Configuration.objects.filter(entity='proc',
is_customer_visible=True)
for config_item in extented_configurations:
kwargs = {
'label': "123",
'required': False
}
field_class = forms.CharField
self.fields[config_item.name] = field_class(**kwargs)
When I print out the fields at the end of the init, I can see that the new fields have been added, however when I load the page I can only see the "test_above" field.
In my admin.py module I have registered the model to an admin class that I have created in another module:
from X.models import Process
from X.model_admins import ProcessAdmin
admin.site.register(Process, ProcessAdmin)
Here is the ProcessAdmin snippet model_admin module:
class ProcessAdmin(admin.ModelAdmin):
list_display = ['name']
def get_form(self, request, obj=None, **kwargs):
from X.admin_forms import ProcessCreateForm
defaults = {}
defaults['form'] = ProcessCreateForm
defaults.update(kwargs)
return super().get_form(request, obj, **defaults)
The end goal of this is when an admin user is adding a new process, then they should be able to add new 'ProcessConfiguration' that are associated with the model that they are creating.
Is this the right way to approach this issue?
python django python-3.x django-models django-forms
add a comment |
I have 3 models "Configuration", "Process", and "ProcessConfiguration" as defined below:
class Configuration(models.Model):
name = models.CharField(max_length=MAX_CONFIGURATION_NAME_LEN,
unique=True, db_index=True)
description = models.TextField(blank=True)
validation = models.CharField(max_length=MAX_CONFIGURATION_VALIDATION_LEN,
blank=True)
entity = models.CharField(max_length=MAX_CONFIGURATION_ENTITY_LEN,
blank=False)
is_customer_visible = models.BooleanField(default=False, editable=True)
class ProcessConfiguration(models.Model):
process = models.ForeignKey(Process, on_delete=models.CASCADE, db_index=True)
configuration = models.ForeignKey(Configuration, on_delete=models.CASCADE, db_index=True)
value = models.TextField()
created = models.DateTimeField(editable=False, auto_now_add=True, db_index=True)
def __str__(self):
return self.process.name + ": " + self.configuration.name + " = " + self.value[:80]
class Meta:
unique_together = ('process', 'configuration')
class Process(models.Model):
name = models.CharField(max_length=MAX_PROCESS_NAME_LEN)
What I am trying to do is to add a new CharFeild to the Process admin form for each of the Configuration objects that have a particular entity flag set.
I thought I would be able to do this in a similar way to how I have added other fields to forms, but within a loop.
class ProcessCreateForm(forms.ModelForm):
test_above = forms.CharField()
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
extented_configurations =
Configuration.objects.filter(entity='proc',
is_customer_visible=True)
for config_item in extented_configurations:
kwargs = {
'label': "123",
'required': False
}
field_class = forms.CharField
self.fields[config_item.name] = field_class(**kwargs)
When I print out the fields at the end of the init, I can see that the new fields have been added, however when I load the page I can only see the "test_above" field.
In my admin.py module I have registered the model to an admin class that I have created in another module:
from X.models import Process
from X.model_admins import ProcessAdmin
admin.site.register(Process, ProcessAdmin)
Here is the ProcessAdmin snippet model_admin module:
class ProcessAdmin(admin.ModelAdmin):
list_display = ['name']
def get_form(self, request, obj=None, **kwargs):
from X.admin_forms import ProcessCreateForm
defaults = {}
defaults['form'] = ProcessCreateForm
defaults.update(kwargs)
return super().get_form(request, obj, **defaults)
The end goal of this is when an admin user is adding a new process, then they should be able to add new 'ProcessConfiguration' that are associated with the model that they are creating.
Is this the right way to approach this issue?
python django python-3.x django-models django-forms
I have 3 models "Configuration", "Process", and "ProcessConfiguration" as defined below:
class Configuration(models.Model):
name = models.CharField(max_length=MAX_CONFIGURATION_NAME_LEN,
unique=True, db_index=True)
description = models.TextField(blank=True)
validation = models.CharField(max_length=MAX_CONFIGURATION_VALIDATION_LEN,
blank=True)
entity = models.CharField(max_length=MAX_CONFIGURATION_ENTITY_LEN,
blank=False)
is_customer_visible = models.BooleanField(default=False, editable=True)
class ProcessConfiguration(models.Model):
process = models.ForeignKey(Process, on_delete=models.CASCADE, db_index=True)
configuration = models.ForeignKey(Configuration, on_delete=models.CASCADE, db_index=True)
value = models.TextField()
created = models.DateTimeField(editable=False, auto_now_add=True, db_index=True)
def __str__(self):
return self.process.name + ": " + self.configuration.name + " = " + self.value[:80]
class Meta:
unique_together = ('process', 'configuration')
class Process(models.Model):
name = models.CharField(max_length=MAX_PROCESS_NAME_LEN)
What I am trying to do is to add a new CharFeild to the Process admin form for each of the Configuration objects that have a particular entity flag set.
I thought I would be able to do this in a similar way to how I have added other fields to forms, but within a loop.
class ProcessCreateForm(forms.ModelForm):
test_above = forms.CharField()
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
extented_configurations =
Configuration.objects.filter(entity='proc',
is_customer_visible=True)
for config_item in extented_configurations:
kwargs = {
'label': "123",
'required': False
}
field_class = forms.CharField
self.fields[config_item.name] = field_class(**kwargs)
When I print out the fields at the end of the init, I can see that the new fields have been added, however when I load the page I can only see the "test_above" field.
In my admin.py module I have registered the model to an admin class that I have created in another module:
from X.models import Process
from X.model_admins import ProcessAdmin
admin.site.register(Process, ProcessAdmin)
Here is the ProcessAdmin snippet model_admin module:
class ProcessAdmin(admin.ModelAdmin):
list_display = ['name']
def get_form(self, request, obj=None, **kwargs):
from X.admin_forms import ProcessCreateForm
defaults = {}
defaults['form'] = ProcessCreateForm
defaults.update(kwargs)
return super().get_form(request, obj, **defaults)
The end goal of this is when an admin user is adding a new process, then they should be able to add new 'ProcessConfiguration' that are associated with the model that they are creating.
Is this the right way to approach this issue?
python django python-3.x django-models django-forms
python django python-3.x django-models django-forms
edited Nov 21 at 20:04
asked Nov 21 at 2:05
NeuroWinter
5010
5010
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
I managed to sort this out by using the admin.StackedInline
class:
class ProcessConfigurationInline(admin.StackedInline):
"""
Inline form for process configurations.
"""
model = ProcessConfiguration
config_formset = modelformset_factory(Configuration, fields=('__all__'))
extra = 1
def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
"""
Limit the types of configuration items you can add.
"""
field = super(ProcessConfigurationInline, self).
formfield_for_foreignkey(db_field, request, **kwargs)
if db_field.name == 'configuration':
field.queryset = field.queryset.filter(entity='process')
And then adding this as to the process admin class using this:
inlines = [ProcessConfigurationInline]
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53404343%2fadd-a-dynamic-number-of-fields-to-django-admin-form%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
I managed to sort this out by using the admin.StackedInline
class:
class ProcessConfigurationInline(admin.StackedInline):
"""
Inline form for process configurations.
"""
model = ProcessConfiguration
config_formset = modelformset_factory(Configuration, fields=('__all__'))
extra = 1
def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
"""
Limit the types of configuration items you can add.
"""
field = super(ProcessConfigurationInline, self).
formfield_for_foreignkey(db_field, request, **kwargs)
if db_field.name == 'configuration':
field.queryset = field.queryset.filter(entity='process')
And then adding this as to the process admin class using this:
inlines = [ProcessConfigurationInline]
add a comment |
I managed to sort this out by using the admin.StackedInline
class:
class ProcessConfigurationInline(admin.StackedInline):
"""
Inline form for process configurations.
"""
model = ProcessConfiguration
config_formset = modelformset_factory(Configuration, fields=('__all__'))
extra = 1
def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
"""
Limit the types of configuration items you can add.
"""
field = super(ProcessConfigurationInline, self).
formfield_for_foreignkey(db_field, request, **kwargs)
if db_field.name == 'configuration':
field.queryset = field.queryset.filter(entity='process')
And then adding this as to the process admin class using this:
inlines = [ProcessConfigurationInline]
add a comment |
I managed to sort this out by using the admin.StackedInline
class:
class ProcessConfigurationInline(admin.StackedInline):
"""
Inline form for process configurations.
"""
model = ProcessConfiguration
config_formset = modelformset_factory(Configuration, fields=('__all__'))
extra = 1
def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
"""
Limit the types of configuration items you can add.
"""
field = super(ProcessConfigurationInline, self).
formfield_for_foreignkey(db_field, request, **kwargs)
if db_field.name == 'configuration':
field.queryset = field.queryset.filter(entity='process')
And then adding this as to the process admin class using this:
inlines = [ProcessConfigurationInline]
I managed to sort this out by using the admin.StackedInline
class:
class ProcessConfigurationInline(admin.StackedInline):
"""
Inline form for process configurations.
"""
model = ProcessConfiguration
config_formset = modelformset_factory(Configuration, fields=('__all__'))
extra = 1
def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
"""
Limit the types of configuration items you can add.
"""
field = super(ProcessConfigurationInline, self).
formfield_for_foreignkey(db_field, request, **kwargs)
if db_field.name == 'configuration':
field.queryset = field.queryset.filter(entity='process')
And then adding this as to the process admin class using this:
inlines = [ProcessConfigurationInline]
answered Dec 3 at 19:26
NeuroWinter
5010
5010
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53404343%2fadd-a-dynamic-number-of-fields-to-django-admin-form%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown