Re-Use of CBV in a different app - django

I need some help in understanding how to implement a photo upload in 2 different app and keeping my project DRY. I have an app (gallery) where I defined 3 different view (it's practically an implementation of django-jquery-file-upload example in git: https://github.com/sigurdga/django-jquery-file-upload)
class PictureCreateView(CreateView)
...
class PictureDeleteView(DeleteView):
...
class PictureListView(ListView):
...
This 3 class are used in the same template to choose multiple photo to upload (and eventually delete) to the server. Everything works fine within the gallery app but now I'd like to use all there 3 views in 2 different app (and models). The gallery models is the following:
class Picture(models.Model):
file = models.ImageField()
place = models.ForeignKey(
'app_place.Poi',
related_name='places',
null=True, blank=True,
)
event = models.ForeignKey(
'app_event.Event',
related_name='events',
null=True, blank=True,
)
So that each photo could be related to an event (or place). I'd like to use the 3 views from the gallery app in the event and place DetailView (all authenticated users can add photo to places or events) which belongs to 2 different apps... what is the correct approach? Trying to define the 3 gallery views as mixin? Or call them using the get_context_data? I don't know how to proceed and nay help/suggestion is wellcome

Related

Wagtail Create Snippet from the frontend to accepts Images (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.

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.

Possibility to upload Wagtail documents to a subfolder of /documents/

I am serving my Django-Wagtail media files trough Amazon S3 and now I reached a point where I need to define a customized Document Class which creates "restricted" documents (only accesible if you are logged). This documents will have a special access that will say to my S3 bucket "hey! just deliver this files If they are requested from this "foo_url" but not from anywhere else", since they will be shown to logged users only. I thought of this to prevent restricted urls to spread out.
That's why I am trying to define this Wagtail Document class to be stored in a subfolder of /documents/ and just tell Amazon what to do with that subfolder.
dummy_code_that_doesnt_work:
class RestrictedDocument(Document):
def get_upload_to(self, filename):
folder_name = 'restricted'
filename = self.file.field.storage.get_valid_name(filename)
return os.path.join(folder_name, filename)
"""
Snippet containing restricted documents
"""
#register_snippet
#python_2_unicode_compatible # provide equivalent __unicode__ and __str__ methods on Python 2
class FooSnipet(models.Model):
rectricted_document_1 = models.ForeignKey(
'RestrictedDocument',
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name='+',
)
rectricted_document_2 = models.ForeignKey(
'RestrictedDocument',
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name='+',
)
....
and many more
....
Maybe I am overcomplicating all this and there is another way of doing. Any suggestion will be super welcome! Thank you veeery much :)
The Document model doesn't support a get_upload_to method like images do. However, as of Django 1.10 it's possible to override the file field of AbstractDocument:
from wagtail.wagtaildocs.models import AbstractDocument
class RestrictedDocument(AbstractDocument):
file = models.FileField(upload_to='restricted', verbose_name=_('file'))
I'm not sure that this will help much, though - the views in the Wagtail admin that handle document uploads have no way of knowing that they should save the document through the RestrictedDocument model, rather than the default Document class.
Implementing view restrictions on documents within Wagtail is currently a work in progress (https://github.com/wagtail/wagtail/pull/3245, https://github.com/wagtail/wagtail/issues/1420).

Django permissions

I would love to have more granular permission in my Django project, but can't decide what app to use.
What I have is something like:
class Item(models.Model):
name = models.CharField(max_length=64, unique=True)
description = models.CharField(max_length=128, default='')
logo = ImageField(upload_to=/tmp, blank=True, null=True)
Now with Django standard permissions I have the possibility to choose between add, change and delete, what I want to have is an extended change permission, to offer the ability to give group rights only to change the logo for example, but disallow that same group to modify the item description. I don't want or need a user to entry relation, but simply give the possibility to different groups to edit single fields of a model using the standard admin interface. I'm even not sure if I am talking about per-object permission?
Does anyone know what's best to use or how I would implement it myself? I could also imagine to have read-only users who can access/read everything but won't be able to modify, this isn't possible neither.
Thanks for any help.
The most flexible but way would be to:
write some custom permissions (i.e. can_modify_descr)
write yur own Forms or ModelForms
write Views to render your specified forms.
finally you'd have to override some django admin templates and render your Forms in templates that extend some standard django admin templates.
As far as I can see this is the only way to achieve what you want, but also requires a lot of work.
One simple way to achieve that is to create many ModelAdmin for the same model (one for each "group"). To do that you need to create one Proxy Models for each "group" like this:
models.py
class Item(models.Model):
name = models.CharField(max_length=64, unique=True)
description = models.CharField(max_length=128, default='')
logo = ImageField(upload_to=/tmp, blank=True, null=True)
class ItemGroup1(Item):
class Meta:
proxy = True
admin.py
class ItemAdmin(models.ModelAdmin):
...
class ItemGroup1Admin(models.ModelAdmin):
readonly_fields = ('logo', 'description')
And then you just need to set the permissions of group 1 to only have access to ItemGroup1, etc.
See this post for more info: Using Proxy Models to Customize the Django Admin
If you want to handle this sort of thing beyond your admin site, take a look at django-logical-rules, where you can write your rules in python and access them from views or within a template;

Help with designing models for a Django 'Project' app with 1 or more urls in it (variable), with editing at once in admin interface

i'm building a simple app for Django and I'm facing some problems with my models design, and the use of 'inlines' in the administration interface.
The app is to manage projects.
A project consists of a name, a description, other fields (e.g. tags...) and of multiple urls (like project url, source code repository url) but the number is not fixed, they can have 1, 2 or more urls (i think 0 will never be the case).
I have first created simple models like:
class Url(models.Model):
name = models.CharField(max_length=100)
url = models.URLField()
class Project(models.Model):
name = models.CharField(max_length=100)
description = models.CharField(max_length=300)
...
urls = models.ManyToManyField(Url, blank=True)
but with these models I did't manage to have an admin interface where i can had a project and add at the same time one or more urls.
I have tried to use 'inlines' in the admin website like indicated in the doc but without success.
I'm not even sure the models/database design (e.g. urls won't be reused in various projects, and the manytomanyfield let you choose between allready existing urls which may not be necessary), but I don't know what can be other solutions (lists, ...).
Can anyone help me with this (simple i think) problem?
Indicate me some useful guidelines to choose a models/db design?
Even maybe point me to some example code implementing this sort of problem, with admin interface as indicated?
Thanks for responses and don't hesitate to ask details if it's not clear enough.
I think I have found the beginning of a solution to my problem.
Changing the ManyToManyField in Project to a ForeignKey in Url, and creating inlines like indicated below
# models.py
class Project(models.Model):
name = models.CharField(max_length=100)
description = models.CharField(max_length=300)
...
class Url(models.Model):
name = models.CharField(max_length=100)
url = models.URLField()
project = models.ForeignKey(Project)
# admin.py
class UrlInline(admin.TabularInline):
model = Url
class ProjectAdmin(admin.ModelAdmin):
inlines = [ UrlInline, ]
admin.site.register(Project,ProjectAdmin)
Now i can add urls specific to a project, edit them, even delete them :)
And I don't see urls used in other projects.
I think it does the job to begin, and, for information, I found ideas on the right sidebar looking at this other post Django admin - inline inlines (or, three model editing at once) :)