Empty ChainedManyToMany In Admin When Editing
See original GitHub issueYou MUST use this template when reporting issues. Please make sure you follow the checklist and fill in all of the information sections below.
All versions of django-smart-selects prior to version 1.2.8 are vulnerable to an XSS attack as detailed in issue 171. As a result, all previous versions have been removed from PyPI to prevent users from installing insecure versions. All users are urged to upgrade as soon as possible.
Checklist
Put an x
in the bracket when you have completed each task, like this: [x]
- This issue is not about installing previous versions of django-smart-selects older than 1.2.8. I understand that previous versions are insecure and will not receive any support whatsoever.
- I have verified that that issue exists against the
master
branch of django-smart-selects. - I have searched for similar issues in both open and closed tickets and cannot find a duplicate.
- I have debugged the issue to the
smart_selects
app. - I have reduced the issue to the simplest possible case.
- I have included all relevant sections of
models.py
,forms.py
, andviews.py
with problems. - I have used GitHub Flavored Markdown to style all of my posted code.
This appears to be similar to issue 212 but I’m running “master” and still having the issue described below.
Steps to reproduce
- Create models with ChainedManyToMany field
- Using Django admin, add “parent” records and “child” record (N:N populates as expected)
- Edit “child” record in Django admin interface
Actual behavior
N:N select box is empty (no options to select and existing selections do not appear)
Expected behavior
Previously selected options appear selected. Any remaining valid options appear as available to select.
The “horizontal” option has no effect (select box is empty regardless of horizontal being true or false).
My Django version is 1.11.6 (though I have experienced this issue throughout the 1.11.x series).
The following JavaScript files are loaded:
/myapp/admin/jsi18n/ /myapp/static/admin/js/core.js /myapp/static/admin/js/vendor/jquery/jquery.min.js /myapp/static/admin/js/jquery.init.js /myapp/static/admin/js/admin/RelatedObjectLookups.js /myapp/static/admin/js/actions.min.js /myapp/static/admin/js/urlify.js /myapp/static/admin/js/prepopulate.min.js /myapp/static/admin/js/vendor/xregexp/xregexp.min.js https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js /myapp/static/smart-selects/admin/js/chainedm2m.js /myapp/static/smart-selects/admin/js/bindfields.js /myapp/static/admin/js/SelectBox.js /myapp/static/admin/js/SelectFilter2.js /myapp/static/smart-selects/admin/js/chainedfk.js
The JavaScript console in Chrome shows the following request being made:
https://example.com/myapp/chaining/filter/inventory/URL/biz_app/inventory/JBossDomain/web_urls/89/
When I hit that URL manually the following data is displayed:
[{"display": "http://customer1.example.com:80", "value": 299}, {"display": "http://customer2.example.com:8230", "value": 301}, {"display": "https://customer3.example.com:443", "value": 300}]
Relevant admin.py
:
class JBossDomainAdmin(admin.ModelAdmin):
model = JBossDomain
list_display = ['master_fqdn', 'app_url', 'biz_app']
list_select_related = True
admin.site.register(JBossDomain, JBossDomainAdmin)
Relevant models.py
- JBossDomain.web_urls is the field specific to this report:
class BizApp(models.Model):
class Meta:
verbose_name = 'Business Application'
verbose_name_plural = 'Business Applications'
unique_together = ('biz_service', 'ba_name')
# 1:n with Business Service
biz_service = models.ForeignKey(
BizService,
on_delete=models.PROTECT,
verbose_name='Business Service',
)
ba_name = models.CharField(
'Business Application Name',
max_length=64,
)
def __str__(self):
return '{} : {}'.format(
self.biz_service,
self.ba_name,
)
class URL(models.Model):
class Meta:
verbose_name = 'URL'
verbose_name_plural = 'URLs'
unique_together = (
('fwd_record', 'proto'),
('fwd_record', 'port'),
('fwd_record', 'proto', 'port'),
)
# 1:n with Business Application
biz_app = models.ForeignKey(
BizApp,
on_delete=models.PROTECT,
verbose_name='Business Application',
)
# 1:n with DNS record
# This should always point at an A or CNAME
fwd_record = ChainedForeignKey(
DNSRecord,
chained_field='biz_app',
chained_model_field='biz_app',
on_delete=models.PROTECT,
verbose_name='DNS A/CNAME Record',
limit_choices_to={'rtype__in': [DNSRecord.A, DNSRecord.CNAME]},
)
# Protocol options
HTTP = 'HTTP'
HTTPS = 'HTTPS'
PROTO_CHOICES = (
(HTTP, 'http'),
(HTTPS, 'https'),
)
proto = models.CharField(
'Protocol',
max_length=5,
choices=PROTO_CHOICES,
)
port = models.PositiveIntegerField(
'TCP Port',
validators=[MaxValueValidator(65535)],
)
is_https_redirector = models.BooleanField(
'HTTPS Redirector?',
default=False,
)
# 1:n with LTM virtual server
ltm_vs = models.ForeignKey(
LTMVirtualServer,
on_delete=models.PROTECT,
verbose_name='LTM Virtual Server',
blank=True,
null=True,
)
# 1:1 with Docker container
# We want this to be a ChainedOneToOne but that doesn't exist
container = models.OneToOneField(
DockerContainer,
on_delete=models.PROTECT,
verbose_name='Docker Container',
blank=True,
null=True,
)
def __str__(self):
return '{}://{}:{}'.format(
dict(self.PROTO_CHOICES)[self.proto],
self.fwd_record.dns_src,
self.port,
)
class JBossDomain(models.Model):
class Meta:
verbose_name = 'JBoss Domain'
verbose_name_plural = 'JBoss Domains'
# 1:n with Business Application
biz_app = models.ForeignKey(
BizApp,
on_delete=models.PROTECT,
verbose_name='Business Application',
)
master_fqdn = models.CharField(
'Master FQDN',
# Per RFC
max_length=255,
unique=True,
validators=[validate_lower],
)
# n:n with URL
# Only allow URLs from the parent (biz app)
web_urls = ChainedManyToManyField(
URL,
horizontal=True,
chained_field='biz_app',
chained_model_field='biz_app',
verbose_name='Web URLs',
related_name='jbossdomains_web_urls',
)
# 1:n with URL
# Only allow URLs from the parent (biz app)
app_url = ChainedForeignKey(
URL,
chained_field='biz_app',
chained_model_field='biz_app',
on_delete=models.PROTECT,
verbose_name='App URL',
related_name='jbossdomains_app_url',
)
@property
def console(self):
"Returns the console URL."
return 'http://{}:9990/console/App.html'.format(self.master_fqdn)
def __str__(self):
return self.master_fqdn
Issue Analytics
- State:
- Created 6 years ago
- Comments:29 (7 by maintainers)
@jbnance no problem, community projects have ups and downs. You are welcome back anytime.
Sorry, but I had to remove Smart Selects from our code base. No offense intended to anyone involved - it is a great idea and when it worked it was awesome - I just needed something with a more responsive community.