Django Compressor with dynamic LESS file raises a

2019-07-31 15:53发布

问题:

I had to come up with quite a complicated setup to enable database based styling options for users. Users enter styles (like background color, font face, etc...) in the django admin backend.

I am creating a dynamic LESS file by rendering a template view as plain text view like so:

views.py:

class PlainTextView(TemplateView):
    """
    Write customized settings into a special less file to overwrite the standard styling
    """
    template_name = 'custom_stylesheet.txt'

    def get_context_data(self, **kwargs):
        context = super(PlainTextView, self).get_context_data(**kwargs)
        try:
            #get the newest PlatformCustomizations dataset which is also activated
            platform_customizations = PlatformCustomizations.objects.filter(apply_customizations=True).order_by('-updated_at')[0]
        except IndexError:
            platform_customizations = ''

        context.update({
            'platform_customizations': platform_customizations,
        })
        return context


    def render_to_response(self, context):
        return super(PlainTextView, self).render_to_response(context, content_type='plain/text')

The template custom_stylesheet.txt looks kind of like this. It takes the database styling entries the users entered in the admin backend:

@CIBaseColor: {{ dynamic_styles.ci_base_color }};
@CIBaseFont: {{ dynamic_styles.ci_base_font }};
...etc...

Now I include this dynamic less files in my main.less file with other normal static LESS files. Like so:

main.less:

@import "bootstrap_variables.less";

//this is the dynamicly created custom stylesheet out of the dynamic_styles app
@import url(http://127.0.0.1:8000/dynamic_styles/custom_stylesheet.less);

//Other styles
@import "my_styles.less";

This setup works fine. The dynamic variables out of my database get rendered into the template and LESS compiles all my less files together.

I have a problem when pushing the code to my production setup where I compile the LESS server side and compress it with django-compressor.

I get the following error:

FilterError: [31mFileError: 'http://127.0.0.1:8000/dynamic_styles/custom_stylesheet.less' wasn't found.
[39m[31m in [39m/home/application/***/media/static-collected/styles/less/main.less[90m:13:0[39m
[90m12 //this is the dynamicly created custom stylesheet out of the dynamic_styles app[39m
13 [7m[31m[1m@[22mimport url(http://127.0.0.1:8000/dynamic_styles/custom_stylesheet.less);[39m[27m
[90m14 [39m[0m

Has anybody ever experienced problems with django compressor like that? Does it have problems with dynamically created files like this? Could the absolute url be a problem?

Could you think of another solution get dynamically generated less files working with django compressor?

回答1:

I guess Django-Compressor can't read dynamically created less files which are only available "on-the-fly" if you hit the url. At least I did not get it working. Also the file needs to be on the COMPRESS_ROOT.

Now I write the less file to disk physically every time the model gets saved. Here's the code. It still needs some improvement like try except, etc. But it works:

 def save(self, *args, **kwargs):

    #todo add try except
    less_file = open(os.path.join(settings.PROJECT_ROOT, 'media', 'static', "styles", "less", "custom_stylesheet.less"), "w")
    less_file.write(render_to_string('template/custom_stylesheet.txt', {'platform_customizations': self}))
    less_file.close()

    super(PlatformCustomizations, self).save(*args, **kwargs)