wagtail admin images and document tags - wagtail

Is there anyway how to disable images/document tags? I use lots of collections in my project and the fact that any user can see tags from any collection is unwanted, therefore I would rather not have tags at all. I can't find a way how to dissable them to t user won't see them.
Any advise?

I have found a way around editing document/images forms using signals. If anyone is interested my solution is bellow
from django.dispatch import receiver
from django.db.models.signals import pre_init
from wagtail.documents.models import Document
from wagtail.images.models import Image
#receiver(pre_init, sender=Document)
def document_form_hide_tags(sender, instance=None, created=False, **kwargs):
'''
hides tags from the document form
'''
Document.admin_form_fields = (
'title',
'file',
'collection',
# 'tags'
)
#receiver(pre_init, sender=Image)
def image_form_hide_tags(sender, instance=None, created=False, **kwargs):
'''
hides tags from the image form
'''
Image.admin_form_fields = (
'title',
'file',
'collection',
# 'tags',
'focal_point_x',
'focal_point_y',
'focal_point_width',
'focal_point_height',
)

Related

Prevent field from being save into Django Model

I am creating a form that allow user to edit all the fields in the form. I would like to check with the community if there is a viable solution to display say the object ID in the form itself but when the user submit the updates, it will save the other fields and will not save the object ID?
Currently, I am prevented from saving due to the error: "ID already in database"
I have tried to add the attributes "readonly"; "disabled" but these are not working.
I am using {{form.as_p}} to display all the fields in my templates (HTML)
My apologies that I am not able to show the codes as it is on my corporate server.
Much help appreciated
Let assume that user want to update 'First name', then here below is technic to update authenticated user 'First name':
forms.py
from django import forms
from django.contrib.auth.models import User
class EditUserForm(forms.ModelForm):
class Meta:
model = User # You can provide model class here to update
fields = ['first_name'] # You can provide any field you want to update
views.py
from .forms import EditUserForm
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required
#login_required
def edit_user(request): # give a url path with name='edit_user' in urls.py file
user = User.objects.filter(id=request.user.id).first() # Here you can write your model name which you want to update
form = EditUserForm(request.POST or None, instance=user)
if form.is_valid():
form.save() # that's it
return redirect('/') # redirect to wherever you want
return render(request,'update.html',{'form':form}) # provide template name here
update.html
<h1>Update First name:- </h1>
<form action="{% url 'edit_user' %}" method=POST>
{{form.as_p}}
<button type='submit'>Update</button>
</form>
Now, try it manually and you able to change the 'First name'. After that you get some confidence how you update any field of models.

Wagtail Custom Pages?

I'm totally new to Wagtail/ Django.
Here's what I am trying to achieve:
I'd like to have an ability in the backend of my Wagtail CMS install to create 'pages' or 'posts' that follow a strict template.
The template would have custom fields like 'header' and aim content' etc.
I'm sure that this is possible, I'd just be interested to know how I'd go about achieving this?
For example, does anyone know if Wagtail has a plugin or other to enable this?
Thanks for all help/ direction.
You want to create pages and posts that follow a strict template: that's exactly what Django and Wagtail let you do. But there's one catch: Wagtail takes this a step further and lets you move entire sections of a page — these are called Streamfields. It's an amazing feature, to be honest.
Here's an example to get you started (note: this is untested and not linted)
# -*- coding: utf-8 -*-
"""Basic Page model."""
from django.db import models
from wagtail.admin.edit_handlers import FieldPanel, MultiFieldPanel, StreamFieldPanel
from wagtail.core.fields import StreamField
from wagtail.core.models import Page
from your_custom_app.streams import streamfields
class BasicPage(Page):
"""A basic page class."""
template = "templates/pages/basic_page.html"
parent_page_type = ["pages.HomePage", "pages.BasicPage"]
subpage_types = ["pages.BasicPage"]
header = models.CharField(max_length=100)
content = StreamField(
('streamfield_name', streamfields.CustomStreamfield()),
# ... More streams
null=True,
blank=True,
)
# Other additional fields you want on your page.
# Panels are how you lay out your pages in the /admin/
content_panels = [
FieldPanel("title", classname="full title"),
FieldPanel("header"),
# FieldPanel("other_fields"),
StreamFieldPanel("content"),
]
settings_panels = Page.settings_panels + [] # Custom settings panel
promote_panels = Page.promote_panels + [] # Custom promote panel
class Meta:
"""Meta information."""
verbose_name = "Basic Page"
verbose_name_plural = "Basic Pages"
You can also download and setup the Wagtail Bakery Demo, it has a lot of great examples in it.

Get orderable fields - Django Rest

I have a ReactJS table that uses fetch API to get the data from a Django server using Rest. I've defined the viewset to use OrderingFilter and specified the ordering_fields as so:
class RecipientViewSet(BaseViewSetClass):
permission_classes = (IsAuthenticated,)
serializer_class = serializers.RecipientsSerializer
filter_backends = (filters.OrderingFilter,)
ordering_fields = (
'id',
'externalID',
'firstname',
'lastname',
)
It works great, but I want to know if there's a method of getting from the ordering_fields from the server with fetch, so that I can add a sort icon only for the table headers that can be used to set the data's ordering.
I should add that in the Django REST Framework GUI I can click "Filters" button and view all possible filters for this viewset, and that's exactly what I want to get with ReactJS.
Thanks for any help!
I don't think there is a way to get the ordering fields out of the box via an API call, but you can always add an endpoint to return them:
from rest_framework import viewsets
from rest_framework.decorators import list_route
class MyViewSet(viewsets.GenericViewSet):
ordering_fields = ('a', 'b')
#list_route
def get_ordering_fields(self, request):
return self.ordering_fields
This way calling /your_endpoint/get_ordering_fields/ will return the list of ordering fields defined in the class. You can apply any formatting before returning them if you wish.
Also keep in mind that this behavior can be implemented in a base or mixin class so it can be reused easily later.
See the docs about list and detail routes.

Django Dynamic model register in admin

I'm using django 1.11 and I tried to to create django dynamic models by referring this link https://code.djangoproject.com/wiki/DynamicModels , by executing each and every step it runs without any issue, but How can I see this created table in django admin panel?
action.py
from django.db import models
from django.contrib import admin
def create_model(name, fields=None, app_label='', module='', options=None, admin_opts=None):
"""
Create specified model
"""
class Meta:
# Using type('Meta', ...) gives a dictproxy error during model creation
pass
if app_label:
# app_label must be set using the Meta inner class
setattr(Meta, 'app_label', app_label)
# Update Meta with any options that were provided
if options is not None:
for key, value in options.iteritems():
setattr(Meta, key, value)
# Set up a dictionary to simulate declarations within a class
attrs = {'__module__': module, 'Meta': Meta}
# Add in any fields that were provided
if fields:
attrs.update(fields)
# Create the class, which automatically triggers ModelBase processing
model = type(name, (models.Model,), attrs)
# Create an Admin class if admin options were provided
if admin_opts is not None:
print admin_opts
class Admin(admin.ModelAdmin):
pass
for key, value in admin_opts:
setattr(Admin, key, value)
admin.site.register(model, Admin)
return model
In Console:
from action import create_model
from django.db import models
fields = {
'first_name': models.CharField(max_length=255),
'last_name': models.CharField(max_length=255),
'__str__': lambda self: '%s %s' (self.first_name, self.last_name),
}
options = {
'ordering': ['last_name', 'first_name'],
'verbose_name': 'valued customer',
}
admin_opts = {}
model = create_model('Person', fields,
options=options,
admin_opts=admin_opts,
app_label='form',
module='project.app.model',
)
I can see no. of fields by
len(model._meta.fields)
But I have no idea of, how to register the created model in admin, and what parameter will come inside admin_opts = {} , how can i do makemigrations and migrate,how can I access this model in views.py, from where i will import this model .Can you guys please help me for this , it will be very useful for me and Thanks in advance.
with connection.schema_editor() as editor:
editor.create_model(Model)
This is from github source code , try it instead of sql_model_create and I try to success in my project,and it's true..
I have worked hard for a long time because I don't find django-dynamic-model in "django 1.10".
I think you forgot to execute this function.
def install(model):
from django.core.management import sql, color
from django.db import connection
# Standard syncdb expects models to be in reliable locations,
# so dynamic models need to bypass django.core.management.syncdb.
# On the plus side, this allows individual models to be installed
# without installing the entire project structure.
# On the other hand, this means that things like relationships and
# indexes will have to be handled manually.
# This installs only the basic table definition.
# disable terminal colors in the sql statements
style = color.no_style()
cursor = connection.cursor()
statements, pending = sql.sql_model_create(model, style)
for sql in statements:
cursor.execute(sql)

django model/modelForm - How to get dynamic choices in choiceField?

i'm experimenting with django and the builtin admin interface.
I basically want to have a field that is a drop down in the admin UI. The drop down choices should be all the directories available in a specified directory.
If i define a field like this:
test_folder_list = models.FilePathField(path=/some/file/path)
it shows me all the files in the directory, but not the directories.
Does anyone know how i can display the folders?
also i tried doing
test_folder_list = models.charField(max_length=100, choices=SOME_LIST)
where SOME_LIST is a list i populate using some custom code to read the folders in a directory. This works but it doesn't refresh. i.e. the choice list is limited to a snapshot of whatever was there when running the app for the first time.
thanks in advance.
update:
after some thinking and research i discovered what i want may be to either
1. create my own widget that is based on forms.ChoiceField
or
2. pass my list of folders to the choice list when it is rendered to the client
for 1. i tried a custom widget.
my model looks like
class Test1(models.Model):
test_folder_ddl = models.CharField(max_length=100)
then this is my custom widget:
class FolderListDropDown(forms.Select):
def __init__(self, attrs=None, target_path):
target_folder = '/some/file/path'
dir_contents = os.listdir(target_folder)
directories = []
for item in dir_contents:
if os.path.isdir(''.join((target_folder,item,))):
directories.append((item, item),)
folder_list = tuple(directories)
super(FolderListDropDown, self).__init__(attrs=attrs, choices=folder_list)
then i did this in my modelForm
class test1Form(ModelForm):
test_folder_ddl = forms.CharField(widget=FolderListDropDown())
and it didn't seem to work.What i mean by that is django didn't want to use my widget and instead rendered the default textinput you get when you use a CharField.
for 2. I tried this in my ModelForm
class test1Form(ModelForm):
test_folder_ddl = forms.CharField(widget=FolderListDropDown())
test_folder_ddl.choices = {some list}
I also tried
class test1Form(ModelForm):
test_folder_ddl = forms.ChoiceField(choices={some list})
and it would still render the default char field widget.
Anyone know what i'm doing wrong?
Yay solved. after beating my head all day and going through all sorts of examples by people i got this to work.
basically i had the right idea with #2. The steps are
- Create a ModelForm of our model
- override the default form field user for a models.CharField. i.e. we want to explcitly say use a choiceField.
- Then we have to override how the form is instantiated so that we call the thing we want to use to generate our dynamic list of choices
- then in our ModelAdmin make sure we explicitly tell the admin to use our ModelForm
class Test1(models.Model):
test_folder_ddl = models.CharField(max_length=100)
class Test1Form(ModelForm):
test_folder_ddl = forms.choiceField()
def __init__(self, *args, **kwargs):
super(Test1Form, self).__init__(*args, **kwargs)
self.fields['test_folder_ddl'].choices = utility.get_folder_list()
class Test1Admin(admin.ModelAdmin):
form = Test1Form
I use a generator:
see git://gist.github.com/1118279.git
import pysvn
class SVNChoices(DynamicChoice):
"""
Generate a choice from somes files in a svn repo
""""
SVNPATH = 'http://xxxxx.com/svn/project/trunk/choices/'
def generate(self):
def get_login( realm, username, may_save ):
return True, 'XXX', 'xxxxx', True
client = pysvn.Client()
client.callback_get_login = get_login
return [os.path.basename(sql[0].repos_path) for sql in client.list(self.SVNPATH)[1:]]

Resources