Wagtail Create Snippet from the frontend to accepts Images (Django) - django

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.

Related

How to add new Foreign Key objects in a Form in Django?

I have a blog that uses Django and currently I am building a page for creating new posts.
In my Post model I have a Foreign Key field that is linked to a ImageField. When rendering the page using a generic class view, the field is displayed as a drop-down as expected, but I would like to add new thumbnails, not only selecting the existing ones, similar to the behavior of the admin page when there is a Foreign Key field, where:
There is a plus sign next to the drop-down
When clicked, shows a pop up where I can upload the image
After uploading the image, return to the main page, where the new option is created in the drop-down
How can I have a behavior similar to the admin's in my page? I tried to implement it as a widget, but the end result is very messy, as it just redirects to the admin page and I have to go back to my post creation page and reload to show the new option.
Alternatively I could just replace the the Foreign Key drop-down with a field to upload a file, but I don't know how, as the foreign key field expects an object not a file.
Here's my simplified models:
class Image(models.Model):
image = models.ImageField()
alt_tag = models.Charfield(max_length=30)
class Post(models.Model):
title = models.CharField(max_length=60)
content = models.TextField()
thumbnail = models.ForeignKey(Image, on_delete=models.SET_NULL)
When rendering a page for creating new posts, I am using a generic class view:
class PostCreateView(CreateView):
model = Post
template_name = '../templates/post_create_form.html'

Django blogs using Rest framework connecting mutliple images to that content in single object

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.

Django admin: many-to-one relationships and creation of new "many" object from existing "one"

Django==1.11.5
I have two models:
class Sheet(models.Model):
canonical_image = models.ForeignKey('images.Image',
blank=True,
null=True,
on_delete=models.PROTECT,
related_name="%(app_label)s_%(class)s_related",
verbose_name=_("canonical image"))
class Image(models.Model):
sheet = models.ForeignKey(Sheet,
on_delete=models.PROTECT,
verbose_name=_("sheet"))
pass
I registered the models for Django admin.
Now when I change the sheet in admin, I see "Canonical image" and a plus button to add an image.
If I press the plus button, a form for creating a new Image appear.
And there is going to be a drop down list with choices sheets. There is a bunch of sheets there.
This is clumsy. I press a plus sign from a definite sheet. That very sheet should be selected for creation a new image.
Could you tell me how to cope with this problem. Maybe to limit the choice to that particular sheet. Or remove the sheet from image creation form and substitute it in input type="hidden".
Or something else. The easier the better.
This should be a comment, but I do not have enough points for that.
But have you looked into creating a ModelAdmin?
Django doc
In a ModelAdmin class, you can also add inlines for other model, which either links to the model you attach the ModelAdmin to, or models that your current model links to.

Django model variables - Unique

I am terribly sorry for the crummy title to this question. I can't think of how to phrase it in a simple context.
I am making a simple photo gallery. The admin can create a gallery page and upload images to it. For each gallery I want there to be a single banner image from one of the photos. The Photo model has a CharField which will tell if its a banner or not. Is there a way to make the variable to allow only one 'B' for every photo that belongs to a Gallery?
You should define a unique_together variable for your class. If names of your fields are album and banner, you should add this line to Meta class of your model.
unique_together = (("album", "banner"),)
Django Documents, unique-together
And i think, using charfield for a boolean value isn't a correct choice. You should change your banner field as BooleanField.
Why don't you create a OneToOne field?
class Gallery(models.Model):
...
banner = models.OneToOneField(Photo)
this way, you have an unique relationship between a gallery and a photo.

Django admin: search for foreign key objects rather than <select>?

My model looks like this:
class Asset(models.Model):
serial_number = models.CharField(max_length=100, unique=True)
asset_tag = models.CharField(max_length=100, unique=True)
class WorkOrder(models.Model):
asset = models.ForeignKey(Asset)
Essentially, a work order is submitted and then an admin assigns an asset to the work order. The asset_tag field is a barcode that we can scan in. When editing the work order in the Django admin, by default the asset field is displayed as a <select> widget. What we want to be able to do is have a search field so that we can scan the asset tag and then search for the right asset in the DB to associate with the work order.
I know you can customize the Django admin foreign key to a hard coded query, but I can't figure out how to get it so it does a search based on a field on the admin page.
Did you take a look at raw_id_fields?
It should be pretty to close to what you're after.
If you are using Django >= 2.0, you can take advantage of a feature called autocomplete_fields. You must define search_fields on the related object’s ModelAdmin because the autocomplete search uses it.
Since you have a ForeignKey relationship to Asset in WorkOrder, in the admin.py of your app add the following:
from django.contrib import admin
#admin.register(Asset)
class AssetAdmin(admin.ModelAdmin):
search_fields = ["serial_number", "asset_tag"]
#admin.register(WorkOrder)
class WorkOrderAdmin(admin.ModelAdmin):
autocomplete_fields = ["asset"]
Add the fields you want to use for searching to search_fields, and add define autocomplete_fields as shown in the code above.
Now you can use the autocomplete_fields from django 2.0.
It's quite neat.