Django-Viewflow, customize archive view - python

I am trying to customize the default /workflow/archive/ view from Viewflow.
(as in http://demo.viewflow.io/workflow/archive/)
I need to remove some of the columns and add some additional ones specific to my task.
I can't seem to find an easy way. I have been digging and have found that I can try to override the class viewflow.frontend.views.AllArchiveListView and adding the mapping
url('^test/', AllArchiveListView.as_view())
but I get no data when doing that (seems like the flow_classes internal parameter is empty when it gets called like that)
I have also tried to create the viewflow/site_archive.html template but seems overkill.
Any ideas that may point me in the right direction would be highly appreciated!

To customize a common frontend list view, you need to replace viewflow.frontend with you own frontend application. To simplify development, you can inherit from viewflow frontend base classes
# apps.py
from django.apps import AppConfig
from viewflow.frontend.apps import ViewflowFrontendConfig
class FrontendConfig(ViewflowFrontendConfig):
viewset = 'frontend.viewset.FrontendViewSet'
def register(self, flow_class, viewset_class=None):
super().register(flow_class, viewset_class=viewset_class)
# views.py
from viewflow.frontend.views import AllTaskListView as BaseAllTaskListView
class AllTaskListView(BaseAllTaskListView):
list_display = [
'task_hash', 'description'
]
# viewset.py
from viewflow.frontend.viewset import FrontendViewSet as BaseFrontendViewSet
class FrontendViewSet(BaseFrontendViewSet):
inbox_view_class = views.AllTaskListView

Related

Django Grappelli_Nested Inlines cannot create new nested lines after initial load

I am looking for a way to create a new nested row, before saving the "owner"-row.
By way of django ticket 9025 I found Grappelli-Nested-Inlines which I have been using.
I have a test project set up based on the instructions found at that link:
from django.contrib import admin
from grappelli_nested.admin import NestedModelAdmin, NestedStackedInline, NestedTabularInline
from .models import *
class MyNestedInline(NestedTabularInline):
model = C
extra = 0
class MyInline(NestedStackedInline):
model = B
extra = 0
inlines = [MyNestedInline,]
class MyAdmin(NestedModelAdmin):
inlines = [MyInline,]
admin.site.register(A, MyAdmin)
My issue is based in the fact that I cannot create a child object before saving the parent. That is to say, the "add another c"-button has no functionality before saving B
Is there a way to achieve this?
I have read through all the posts regarding this that I could find, but I have to say that if the answer is included anywhere, then I didnĀ“t understand it, so please be patient with me.
I should also note, that because of the production code, grappelli is a requirement, so anything that clashes with that will not work.
What i did was to take the templates that django-grappelli-inline provides and use them for use as a template in django-nested-inlines.
class NestedStackedInline(NestedInline):
template = 'admin/edit_inline/stacked.html'
class NestedTabularInline(NestedInline):
template = 'admin/edit_inline/tabular.html'
Where the templates are the ones from django-grappelli-inline

Can I change the template search behavior of class based views?

I have an app called transactions. Within this app I have a model called BatchFile. In my views.py file, I subclass ListView (amongst others). The default behavior is that django thinks batchfile_list.html should be located at:
templates/transactions/batchfile_list.html
That's great, but the folder is getting crowded. I'm able to add "templates/transactions/batchfiles" to TEMPLATE_DIRS, but because the default behavior is to look for appname/modelname_type.html that requires that I put my templates in:
templates/transactions/batchfiles/transactions/batchfile_list.html
when I'd really like it to be in:
templates/transactions/batchfiles/batchfile_list.html
or my optimal result:
templates/transactions/batchfiles/list.html
Are there configuration options that would allow me to do this? I know the optimal result is probably not cleanly achieved, but I was hoping for at least the slightly less optimal result.
Thanks!
The easiest way is to specify template_name:
class MyListView(ListView):
template_name = "transactions/batchfiles/list.html"
An alternative is to override get_template_names:
class MyListView(ListView):
def get_template_names(self):
return ["transactions/batchfiles/list.html"]
Note that it needs to return a list of possible template locations.
In this case there would only be one which is the desired location.

Cleaner / reusable way to emit specific JSON for django models

I'm rewriting the back end of an app to use Django, and I'd like to keep the front end as untouched as possible. I need to be consistent with the JSON that is sent between projects.
In models.py I have:
class Resource(models.Model):
# Name chosen for consistency with old app
_id = models.AutoField(primary_key=True)
name = models.CharField(max_length=255)
#property
def bookingPercentage(self):
from bookings.models import Booking
return Booking.objects.filter(resource=self)
.aggregate(models.Sum("percent"))["percent__sum"]
And in views.py that gets all resource data as JSON:
def get_resources(request):
resources = []
for resource in Resource.objects.all():
resources.append({
"_id": resource._id,
"name": resource.first,
"bookingPercentage": resource.bookingPercentage
})
return HttpResponse(json.dumps(resources))
This works exactly as I need it to, but it seems somewhat antithetical to Django and/or Python. Using .all().values will not work because bookinPercentage is a derived property.
Another issue is that there are other similar models that will need JSON representations in pretty much the same way. I would be rewriting similar code and just using different names for the values of the models. In general is there a better way to do this that is more pythonic/djangothonic/does not require manual creation of the JSON?
Here's what I do in this situation:
def get_resources(request):
resources = list(Resource.objects.all())
for resource in resources:
resource.booking = resource.bookingPercentage()
That is, I create a new attribute for each entity using the derived property. It's only a local attribute (not stored in the database), but it's available for your json.dumps() call.
It sounds like you just want a serialisation of your models, in JSON. You can use the serialisers in core:
from django.core import serializers
data = serializers.serialize('json', Resource.objects.all(), fields=('name','_id', 'bookingPercentage'))
So just pass in your Model class, and the fields you want to serialize into your view:
get_resources(request, model_cls, fields):
documentation here https://docs.djangoproject.com/en/dev/topics/serialization/#id2

Display icons in Django admin for each item

I want to add a specified icon for each model on admin index page. I added an attribute named "picture" on each model then I modified /contrib/admin/sites.py to pass that picture name to template and checked and use it on index.html template of admin to get the result.
I wonder to know if there is a better way
class Product(models.Model):
abbr = models.CharField(max_length=20,unique=True)
title = models.CharField(max_length=200,unique=True)
owner = models.ForeignKey(UserProxy)
des = models.TextField(blank=True,null=True)
picture = 'product.png'
def __unicode__(self):
return self.abbr
class Meta:
none
What You did seems OK, only small tips that can make Your code a little better:
Instead of modifying django/contrib/admin/sites.py You can subclass the AdminSite class (if You didn't do that already).
Modify the AdminSite.index() method to pass not picture, but whole admin class (there is a model_admin variable available in the index() method).
Assign picture in the ModelAdmin classes, not models, to separate admin stuff from models.
The answer from 'Python Fanboy' was so brief but useful to me, I could avoid modifying django base classes
picture field were moved to admin class
I subclass AdminSite as CustomAdminSite and copied index and app_index and made modification
(I don't know if there is a better way than copying whole of index and app_index like overriding)
In urls.py, 'admin.sites.url' replaced by 'custom_site.url'
(custom_site is instance of CustomAdminSite)
I did not want another url instead of '/admin' like '/my_admin' so I have to use instance of CustomAdminSite for all my models even User, Group & Site
I'm using admin_tools, now I've lose my application menu
Any better Idea or solution for my new encountered problems?

Why would I put code in __init__.py files?

I am looking for what type of code would I put in __init__.py files and what are the best practices related to this. Or, is it a bad practice in general ?
Any reference to known documents that explain this is also very much appreciated.
Libraries and frameworks usually use initialization code in __init__.py files to neatly hide internal structure and provide a uniform interface to the user.
Let's take the example of Django forms module. Various functions and classes in forms module are defined in different files based on their classification.
forms/
__init__.py
extras/
...
fields.py
forms.py
widgets.py
...
Now if you were to create a form, you would have to know in which file each function is defined and your code to create a contact form will have to look something like this (which is incovenient and ugly).
class CommentForm(forms.forms.Form):
name = forms.fields.CharField()
url = forms.fields.URLField()
comment = forms.fields.CharField(widget=forms.widgets.Textarea)
Instead, in Django you can just refer to various widgets, forms, fields etc. directly from the forms namespace.
from django import forms
class CommentForm(forms.Form):
name = forms.CharField()
url = forms.URLField()
comment = forms.CharField(widget=forms.Textarea)
How is this possible? To make this possible, Django adds the following statement to forms/__init__.py file which import all the widgets, forms, fields etc. into the forms namespace.
from widgets import *
from fields import *
from forms import *
from models import *
As you can see, this simplifies your life when creating the forms because now you don't have to worry about in where each function/class is defined and just use all of these directly from forms namespace. This is just one example but you can see examples like these in other frameworks and libraries.
One of the best practices in that area is to import all needed classes from your library (look at mongoengine, for example). So, a user of your library can do this:
from coollibrary import OneClass, SecondClass
instead of
from coollibrary.package import OneClass
from coollibrary.anotherpackage import SecondClass
Also, good practice is include in __init__.py version constant
For convenience: The other users will not need to know your functions' exactly location.
your_package/
__init__.py
file1.py/
file2.py/
...
fileN.py
# in __init__.py
from file1 import *
from file2 import *
...
from fileN import *
# in file1.py
def add():
pass
then others can call add() by
from your_package import add
without knowing file1, like
from your_package.file1 import add
Put something for initializing. For example, the logging(this should put in the top level):
import logging.config
logging.config.dictConfig(Your_logging_config)

Categories

Resources