StreamField for native Django Admin or with Grappelli
Project description
Django StreamField
This is a simple realisation of StreamField's idea from Wagtail CMS for plain Django admin or with Grappelli skin.
For editing content we use native popup mechanism in Django admin interface. This allow us to use other field's widgets inside the blocks as is.
For example, if you want to use in your blocks FileBrowseField from django-filebrowser, it will perfectly working without any additional settings.
How to use
Create new app called streamblocks
Put to streamblocks/models.py
some models
that you want to use in your stream field. For example:
# streamblocks/models.py
# one object
class RichText(models.Model):
text = models.TextField(blank=True, null=True)
# list of objects
class ImageWithText(models.Model):
image = models.ImageField(upload_to="folder/")
text = models.TextField(null=True, blank=True)
# StreamField option for list of objects
as_list = True
In streamblocks/models.py
register blocks
for StreamField as list of your block models
# streamblocks/models.py
...
STREAMBLOCKS = [
RichText,
ImageWithText
]
Create templates for each models above, named as lowercase names of the models:
- streamblocks/templates/streamblocks/richtext.html
- streamblocks/templates/streamblocks/imagewithtext.html
And use block_content
as context.
Note: block_content will be single object if no 'as_list' property in your model, and will be a list of objects if there is.
<!--richtext.html-->
<div class="rich-text-block">
{{ block_content|safe }}
</div>
<!--imagewithtext.html-->
<ul class="image-with-text-block">
{% for block in block_content %}
<li>
<img src="{{ block.image.url }}" alt="">
<p>{{ block.text }}</p>
</li>
{% endfor %}
</ul>
Add apps to settings.py
add to INSTALLED_APPS
INSTALLED_APPS = [
...
'streamblocks',
'streamfield',
...
Add StreamField to your model in your application
And add the models that you want to use in this stream as model_list
# models.py
from streamfield.fields import StreamField
class Page(models.Model):
stream = StreamField(
model_list=[
RichText,
ImageWithText
],
verbose_name="Page blocks"
)
Then if you have your 'page' in context, you can get content by calling method page.stream.render()
...
<div class="content">
{{ page.stream.render }}
</div>
...
Admin
Models will automaticaly register in admin
If you want provide custom admin class,
first unregister models and register again, using StreamBlocksAdmin
class.
from django.contrib import admin
from streamfield.admin import StreamBlocksAdmin
from streamblocks.models import RichText
admin.site.unregister(RichText)
@admin.register(RichText)
class RichTextBlockAdmin(StreamBlocksAdmin, admin.ModelAdmin):
pass
Complex Blocks
You may use StreamField as part of blocks and create with that way complex structure
and use {{ block_content.<field_name>.render }}
Cache for reduce the number of database requests
There is two ways of caching:
- Simple cache view with django cache
- Create additional field, for example: 'stream_rendered' and render to this field html in save method
def save(self, *args, **kwargs):
self.stream_rendered = self.stream.render()
super().save(*args, **kwargs)
...and use this field in your html
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for django_streamfield-1.0.1-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 85e9b7644cba66e6551055cafa64a1165853b8f9a244ee2dd2b80c4aea1fda59 |
|
MD5 | 66f01bc238a489cd2ea37a767c311d50 |
|
BLAKE2b-256 | b69d30736b4393c3b1fa5b9b1380271ad7c7f8071fa6cbb1d27c530bd234a19f |