I am new to using Django. And I would like to customize TinyMCE editor for myself. I downloaded it and added to the project as a third part library, did not install it through pip. As you know, there is no free local file uploader in TinyMCE. And I'd like to do 3 things: local image uploder, local audio/video uploader, and local file uploader(with any extension(.pdf, .c, .cpp), this is like how you add a file at the end of a post so that users can download it). And during the realization I had the following issues.
I implemented the local image uploader with TinyMCE file_picker_callback(), and everything works fine. I can upload and edit photos locally, and all of this is displayed on the view page template. The path of each image is recorded in the textarea field in MySQL DB as src atribute. Whether each image should be uploaded(copied) to the MEDIA folder of the site or in a separate field in the MySQL DB. And how it can be implemented, how to write and call the python handler in the js file?
And I still do not download audio / video files. It seems for this in js file, after pressing the button it is necessary to wrap them in the appropriate HTML5 audio/video tags. Then, like the images, copy to the database or Media folder. I also don’t know how to write a Python handler and call it in js.
To upload files, I made my custom plugin and added it to TinyMCE. In plugin I created an input element and stopped there.
Now I have been suffering from it for a month, but I really want to do it. Because having made one full-featured text editor, you can use it many times in other projects. And I think that it needs to many people. If there are interested, then we could realize it together.
There are php handlers on the Internet. But Python handlers for this purpose, I did not find. Any help and tips are welcome. I use Django 2.0.8 and python 3.6. The editor is in the admin panel.
My models.py:
class Post(models.Model):
title = models.CharField(max_length=150)
slug = models.SlugField(unique=True)
description = models.TextField()
content = models.TextField()
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
tags = TaggableManager(blank=True)
author = models.ForeignKey(settings.AUTH_USER_MODEL, default=1, on_delete=models.CASCADE, related_name="post_author")
class Meta:
ordering = ["-created", "-updated"]
admin.py:
class PostModelAdmin(admin.ModelAdmin):
list_display = ["title", "updated", "created"]
list_display_links = ["title"]
list_filter = ["created", "tags"]
search_fields = ["title", "content",]
form = MyTextForm
class Meta:
model = Post
class Media:
js = ('js/tinymce/tinymce.js', 'js/init-tinymce.js',
'//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js',)
admin.site.register(Post, PostModelAdmin)
forms.py
class MyTextForm(forms.ModelForm):
class Meta:
fields = '__all__'
model = Post
widgets = {
'content': forms.Textarea(attrs={'class': 'tinymce', 'label' : 'Content'}),
}
And in the DB images stored as(into the content field):
<p><img src="data:image/jpeg;base64,/9j/4AAQSkZJRgH/2Q==" alt="" width="439" height="604"/></p>
Related
I have a simple snippet using Django Wagtail. I would like to be able to update the logo from a "CreateView" but when it renders in my view it's expecting a foreign key. I would imagine it would be easy to create a from to do this but it's not.
#register_snippet
class MerchantSnippet(models.Model):
name = models.CharField(max_length=255, blank=False, null=False, unique=True)
logo = models.ForeignKey(
'wagtailimages.Image',
null=True,
blank=True,
on_delete=models.SET_NULL,
)
def __str__(self):
return '{} {}'.format(self.user.first_name, self.user.last_name)
panels =[
FieldPanel('name'),
ImageChooserPanel('logo'),
]
edit_handler = TabbedInterface([
ObjectList(panels, heading='Content'),
])
class ProductCreateView(CreateView):
model = ProductSnippet
fields = ['name','logo']
class ProductUpdateView(UpdateView):
model = ProductSnippet
fields = ['name','logo']
When I use the default example in the template I ended up just getting a drop down.
{% render_field field class+="form-control" %}
How would I be able to see an image preview in the event I am updating the snippet and the ability to upload a different one . In the event I am creating a new item the ability to select an upload an image.
The logo field is a foreign key and points to Wagtail Image. Therefore it is a select. If you change the logo field to a ImageField you probably have the behaviour you desire. However, uploaded logos will not appear in the Wagtail Images. That ain't a bad thing. Whenever you want to display a logo, you'd just use the Merchant snippet.
If storing the logo as a Wagtail Image is a must, there are two alternatives:
Alternative 1: Custom form
CreateView and UpdateView are Django generic views and inherit the FormMixin. This means you can specify a custom form_class. Create a custom form with a logo = ImageField(...) and on submit, handle the image data, create a Wagtail Image, and store the Wagtail Image pk on the snippet.
Alternative 2: Multiple forms
Django can handle multiple forms inside a single form tag with a prefix to avoid field name collisions. So you can present both the snippet and the Wagtail image within the same view.
Note: #register_snippet is needed for Wagtail to display CRUD views and enable the snippet chooser in the Wagtail admin interface. But a snippet is a regular Django model. Wagtail Image is a regular Django model too. Forms and generic views are also pure Django concepts. If you dive into this some more, leave Wagtail out of your search queries.
Is there anyway where we can build logic Using django rest framework
where user can add blog with multiple images and content accordingly and when saved
and retrieved it should be able to display the same kind of UI depening up on the frontend app
same like medium platform
Note:
My question isn't about adding multiple images and content using Rest framework
but its about fetching and displaying the data based on how user sent it the server
For eg:
<Image>
content for that image
<Image2>
content for this image
i just want to know how to associate those images to that content
i want to add content to that image
or is there anyway where we can store image and all the content exacty and save it in TextField
I've searched a lot about this but unfortunately I've not found a way to make this happen
Read about relationships in Django (and SQL in general)
django relations
it sounds like you're looking for something like the following:
from django.contrib.auth import get_user_model
from django.contrib.auth.models import AbstractUser
from django.db import models
class CustomUser(AbstractUser):
# Always override the user model provided by Django when starting a project. the docs themselves state that.
pass
class Image(models.Model):
image = models.ImageField()
added = models.DateTimeField(auto_now_add=True)
# using get_user_model to get the User model, always better then referencing User directly
user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE, related_name="user_images",
null=False,
blank=False
)
class ImageContent(models.Model):
title = models.CharField(max_length=140, null=False, blank=False)
content = models.TextField(max_length=500)
image = models.OneToOneField(Image, on_delete=models.CASCADE, null=False, blank=False)
Some notes:
I haven't dealt myself with Images field But I remember it does require a special library (pillow).
getting the data in a certain order should be easy enough if you understand the queryset object:
queryset link
using stuff like order_by will help you return the response in the order you like.
the models I've written here are not the only way to achieve the goal you've set, I strongly recommend reading about relations and models in Django.
I have a blog on django on which any public can post. In post content I am using django-ckeditor RichTextUploadingField.
There is button Browse server for images in ckeditor, that let users browse images of server's upload directory and embed images in post.
But i want to restrict public from browsing images on server when they make post. They should be able upload images only, not browse every image on server that is uploaded.
Here is my models.py
class Article(models.Model):
title = models.CharField(max_length = 200)
content = RichTextUploadingField()
author = models.ForeignKey(User, on_delete= models.CASCADE, null=True)
def __str__(self):
return self.title
Forms.py
class ArticleForm(ModelForm):
class Meta:
model = Article
widgets = {
'content': RichTextUploadingField()
}
A direct setting to remove this functionality isnt provided but CKEDITOR_RESTRICT_BY_USER = True could be used to achieve the same.
Reference from the documentation:
Set the CKEDITOR_RESTRICT_BY_USER setting to True in the project's
settings.py file (default False). This restricts access to uploaded
images to the uploading user (e.g. each user only sees and uploads
their own images). Upload paths are prefixed by the string returned by
get_username. If CKEDITOR_RESTRICT_BY_USER is set to a string, the
named property is used instead. Superusers can still see all images.
NOTE: This restriction is only enforced within the CKEditor media
browser.
I want to upload images not from files but from url's that are submitted by the user, via a put call with a payload like {"image_url":"http://example.com/1.jpg"}.
What is the recommended way of doing this with DRF?
(So far my only option is to reimplement everything manually within my model view set. Is ther any better solution?)
UPDATE:
my serializer was:
class Person(models.Model):
image = models.ImageField() #...
class PersonSerializer(serializers.ModelSerializer):
image = serializers.ImageField(required=False)
class Meta:
model = Person
fields = ('image',)
Does the image actually need to be downloaded to the server? Can you not just save the URL in a CharField and pass it over to the client side for their browser to download? <img src="{{ your_model.image_url }}>". Doing it like this would save alot of storage space on the server and mitigate many security checks required by this process which include making sure the image is not too large! A user could provide an image that is 100GB, which could crash the server. By downloading the image from a web URL and serving it yourself, you are effectively hosting an image which is already being hosted elsewhere.
HOWEVER, If you do wish to download the image, use a python based HTTP request library to download the image. Then use an ImageField in your model to handle the storage and recall of the image. https://docs.djangoproject.com/en/dev/ref/models/fields/#imagefield
If you wished to perform the storage manually, you could save the file in a folder on the server, then save a link to this file in a CharField. Though as far as I am aware, this is essentially what the ImageField would do though for you.
Well, what I ended up doing is using URLField at serialization.
class Person(models.Model):
image = models.ImageField()
class PersonSerializer(serializers.ModelSerializer):
image = serializers.URLField()
# with a custom field serializer it is possible
# to make this field behave both as URLField (handling links)
# and as ImageField (handling files)
class Meta:
model = Person
fields = ('image',)
def save(self):
# handles the upload if the image url is external.
Is there any possible way to resize the original image in the views.py and then load the resized image from the views to the template? I tried using sorl-thumbnail and easy_thumbnail, they works great, but I don't know why, somehow whenever I upload it using the apache server, the server only loads the images uploaded by the django's inbuilt server, and when I load the page again with the django's inbuilt server it loads the uploaded image nicely. So, is there anyway that I can resize the image in the views itself, and then load it in the templates? And if there is, please kindly guide me how do I do it. Thank you!
models.py
class Status(models.Model):
status = models.TextField()
image = ImageField(upload_to=get_upload_file_name, blank=True)
pub_date = models.DateTimeField(default=datetime.now)
creator = models.ForeignKey(User, related_name="creator_set")
likes = models.ManyToManyField(User, through="Like")
class Meta:
ordering = ['-pub_date']
verbose_name_plural = ('Status')
def __unicode__(self):
return self.status
Me, too, I don't understand your problem with generating thumbnails in the template. But if you want to create them in the view (or anywhere else in the python code), that will be possible with sorl thumbnail. In the sorl thumbnail docs, there's the following low level api example:
from sorl.thumbnail import get_thumbnail
im = get_thumbnail(my_file, '100x100', crop='center', quality=99)