Custom widget in separated app not loading media

Hi all,
i’m quite new to Django and i’m trying to integrate a 3rd party component based on css/js.

I already managed to make it work on the final page hard coding it in but i need to publish it in a custom widget in a dedicated app.

I made a testpage on the app that works correctly but when i import the wiget on the field that i need on the actual form it doesn’t load the statics on the page.

I’ve also tried to add the app static folder in STATICFILES_DIRS but collectstatic fails with " Found another file with the destination path ‘path/file.css’. It will be ignored since only the first encountered file is collected. If this is not what you want, make sure every static file has a unique path."

Probably i’m missing something. Any suggestion of what to check?
Thanks in advance.

Please post all STATIC-related settings in your settings.py file along with a description of the directory structure of your project, focusing on the locations where you are storing static files.

Hi Ken,
so for the static setings

STATIC_ROOT = '/var/www/static/'
STATIC_URL = '/static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
STATICFILES_FINDERS = (
    "django.contrib.staticfiles.finders.FileSystemFinder",
    "django.contrib.staticfiles.finders.AppDirectoriesFinder",
    "compressor.finders.CompressorFinder",
)

For the file structure i cannot post it exactly since is work related but the structure is something like:

Containerapp
–>Mainapp
–>static
–>WidgetApp
–>–>static

The static files i need to render are under WidgetApp/static

The form is in the Mainapp and checking it seems it only sees the Containerapp/static

As documented at Writing your first Django app, part 6 | Django documentation | Django, the common pattern for static files within an app is to place those files in an app-specific directory within the static directory within the app.

So in other words, typically you would have:

Containerapp
-> WidgetApp
   -> static
      -> widget

and so your references to a file named style.css within widget would look like
{% static 'widget/style.css' %}

This is the typical layout for app-specific static files to avoid file/directory naming conflicts.

Hi Ken,
thanks for the suggestion i confirm my static are
–>WidgetApp
–>–>static
–>–>–>WidgetApp
–>–>–>–>widget

Sorry for the confusion

So I’m not sure if this means you’ve got it solved or if you still have a question.

Nope i still have the problem i was just confirming that the structure is correct.

Then I think we’re going to need to see the actual path structure, template, and the portion of the log where it’s trying to GET those static files.

I’ll try to give context at the best of my possibility

WidgetApp/widgets.py

class WidgetApp(forms.Textarea):
    template_name = 'template_textarea.html'

    def __init__(self, attrs=None):
        user = '************'
        pass = '************'

        default_attrs = {'cols': '80', 
                         'rows': '20',
                         'servicelink': '**********************************',
                         'jsBaseUrl': '/static/WidgetApp/js',
                         'cssBaseUrl': '/static/WidgetApp/css',
                         'soundsBaseUrl': '/static/WidgetApp/sounds',
                         'user': user,
                         'pass':pass,
                        }
	
        if attrs:
            default_attrs.update(attrs)
        super().__init__(default_attrs)


    class Media:
        css = {
            "all": ["WidgetApp/folder1/css1.css",
                    "WidgetApp/folder2/folder/css2.min.css",
            ]
             
        } 
               
        js = [
            "WidgetApp/folder1/first.js",
            #other scripts here
            "WidgetApp/folder2/last.js",            
            "WidgetApp/js/script.js",
        ]


WidgetApp/templates/template_textarea.html

<div class="WidgetApp_container" id="{{ widget.attrs.id }}_div">
    <textarea name="{{ widget.name }}"{% include "django/forms/widgets/attrs.html" %}>
        {% if widget.value %}{{ widget.value }}{% endif %}
    </textarea>
</div>

WidgetApp/forms.py

from django import forms
from .widgets import WidgetApp

class TestForm(forms.Form):
    text_html = forms.CharField(label='', widget=WidgetApp())

WidgetApp/views.py

from django.http import HttpResponseRedirect
from django.shortcuts import render

from .forms import TestForm

def TestFormView(request):
    if request.method == "POST":
        form = TestForm(request.POST)
        if form.is_valid():
            return HttpResponseRedirect("/thanks/")
    else:
        form = TestForm()

    return render(request, "template.html", {"form": form})

WidgetApp/templates/template.html

<!DOCTYPE html>
<html>
    <head>
        {{ form.media }}
    </head>
    <body>
        <form action="">
            {{ form }}
        </form>
    </body>   
</html>

This above is the WidgetApp where my test url works properly and loads everything as intended.

Mainapp/forms.py

from WidgetApp.widgets import WidgetApp

class ActualForm(forms.ModelForm):
    text_html = forms.CharField(widget=WidgetApp())

Mainapp/views.py

class View():
    model = models.ActualForm
    success_url = reverse_lazy('factualform_list')
    permission_required = ['change_actualform']
    form_class = forms.ActualForm

Form template is complex but the contains the elements

{% load static %}
{{ form.media }}

<!--  -->
<div id="mcewrapper" class="flex-wrapper flex-vfill{% if form.text_html.errors %} has-error{% endif %}">
{{ form.text_html|safe }}
</div>

Hope this helps to clarify the situation. As told before it seems that the widget loading in the Mainapp/forms.py doesn’t load the WidgetApp static files.

There were two issues identified originally, the error in the “collectstatic”, and the issue with the static files not being loaded.

Has the error in collectstatic been resolved?

If so, please show the part of the console log where the desired files are being requested by the browser (and presumably getting a 404), and the html as it exists in the browser that is attempting to load the file.

The previous error with collectstatic was because i was trying to add the WidgetApp static folder to the settings.py (and since it was not useful i removed it).

The fact is that from the console it doesn’t seem it’s trying to get the files ( no 404 errors)

That would imply that you don’t have anything in your template to use those files then. What have you defined that makes you think that those files are going to be loaded?

{% load static %}
{{ form.media }}

isn’t this sufficient?

i’ve tried to replicate the example working in the WidgetApp

<!DOCTYPE html>
<html>
    <head>
        {{ form.media }}
    </head>
    <body>
        <form action="">
            {{ form }}
        </form>
    </body>   
</html>

Or am i missing something else?

That’s why I asked you to post the html as it has been rendered in the browser. I’d like to see what is being generated by what you’ve posted.

You also haven’t posted the view that is trying to render this form. What you posted under Mainapp/views.py is not a valid view.

Hi Ken,
same problem as before since it’ a big corporate app i cannot post it but from what i see it only loads the scripts located in Containerapp/static

Well, unless you can post a minimal example then that demonstrates this same behavior, we probably can’t help. There are just too many different specific things that might be wrong to try and go through them all

Hi Ken,
thinking back on your words i traced back the problem.
I was using the widget only on a copy of the actual form that had another purpose once put on the right one the process works as intended.

Sorry for the confusion but are my first attempts.
Thanks