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
Related
I'm having trouble append extra information to the information_block of the DIN5008 template.
I inherited the sale.order module like suggested here.
I tried override both _compute_l10n_de_template_data functions in the sale.order and the account.move but nothing changes. I can't append nor leave everything empty.
If I look for models in the odoo inteface I can see, that my module inherits the sale.order and account.move model. So I don't think I have an error in my __init__.py files. I can also create new fields, but trying to overwrite those functions won't change the output in the report.
Here is my code for the sale.order model:
from odoo import models, fields, _
from odoo.tools import format_date
class SaleOrder(models.Model):
_inherit = 'sale.order'
l10n_de_template_data = fields.Binary(compute='_compute_l10n_de_template_data')
def _compute_l10n_de_template_data(self):
for record in self:
record.l10n_de_template_data = data = []
if record.state in ('draft', 'sent'):
if record.name:
data.append((_("Quotation No."), record.name))
if record.date_order:
data.append((_("Quotation Date"), format_date(self.env, record.date_order)))
if record.validity_date:
data.append((_("Expiration"), format_date(self.env, record.validity_date)))
else:
if record.name:
data.append((_("Order No."), record.name))
if record.date_order:
data.append((_("Order Date"), format_date(self.env, record.date_order)))
if record.client_order_ref:
data.append((_('Customer Reference'), record.client_order_ref))
if record.user_id:
data.append((_("Salesperson"), record.user_id.name))
if record.partner_id:
data.append((_("Customer"), record.partner_id))
It doesn't matter what I do to _compute_l10n_de_template_data I can't see my changes in an offer or invoice (if I change the function in account.move)
Seems like I'm doing something fundamentally wrong.
You already linked to addon l10n_de_sale in which you can find the definition of _compute_l10n_de_template_data and its DIN 5008 infoblock.
See here.
I ended up adding additional information to the block in the code. After restarting the service it worked well for me.
if record.user_id and record.user_id.mobile:
data.append((_("Mobile"), record.user_id.mobile))
if record.user_id and record.user_id.email:
data.append((_("Email"), record.user_id.email))
if record.commitment_date:
data.append((_("Estimated Delivery"), format_date(self.env, record.commitment_date)))
It shouldn't be forgotten to restart the service to make the changes work.
To have the labels tranlated i generated missing translations in settings and could translate the newly added labels.
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
Basically I have a structure of 3 models in the order:
class Model_A(models.Model):
# (actually, it doesn't matter what type m_aid is...)
m_aid = models.IntegerField(primary_key=True)
# ...
class Model_B(models.Model):
m_bid = models.IntegerField(primary_key=True) # same as previous
m_a = models.ForeignKey('Model_A', db_column='m_aid')
# ...
class Model_C(models.Model):
m_cid = models.IntegerField(primary_key=True) # same as the previous 2
m_b = models.ForeignKey('Model_B', db_column='m_bid')
# ...
What I'm looking for is to use the admin change form templates with a slight difference: in the change_form of Model_A I want to show the change list of its child - Model_B and in the change_form of Model_B I would like to put the change list of Model_C.
Any ideas how to do it?
P.S You might see it as a silly question, but I'm new to django(and python)
You can use inline models to accomplish that.
They will allow you to edit one or more instances of "Model B" when editing an instance of "Model A" and so on. It's not identical to what you see in the change list, but there are two built-in layouts, stacked and tabular, for inlines. Tabular will get you closest in appearance to what you want.
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?
I recently added a new model to my site, and I'm using an admin.py file to specify exactly how I want it to appear in the admin site. It works great, but I can't figure out how to get one of my date fields to include seconds in it's display format. I'm only seeing values like "Aug. 27, 2011, 12:12 p.m." when what I want to be seeing is "Aug. 27, 2011, 12:12*:37* p.m."
Try this in the ModelAdmin:
def time_seconds(self, obj):
return obj.timefield.strftime("%d %b %Y %H:%M:%S")
time_seconds.admin_order_field = 'timefield'
time_seconds.short_description = 'Precise Time'
list_display = ('id', 'time_seconds', )
Replacing "timefield" with the appropriate field in your model, of course, and adding any other needed fields in "list_display".
digging around I ended here but applied a different approach to my app.
Changing django admin default formats could be done changing the django locale formats for every type you want.
Put the following on your admin.py file (or settings.py) to change datetime default format at your django admin.
from django.conf.locale.es import formats as es_formats
es_formats.DATETIME_FORMAT = "d M Y H:i:s"
It will change the ModelAdmin's datetime formats on that file (or whole site if in settings).
It does not breaks admin datetime filters and order features as #Alan Illing has point out in comments .
hope this help in future
Extra info:
You can change it for every available locale in django, which are a lot.
You can change the following formats using this approach
from django.conf.locale.es import formats as es_formats
es_formats.DATETIME_FORMAT
es_formats.NUMBER_GROUPING
es_formats.DATETIME_INPUT_FORMATS
es_formats.SHORT_DATETIME_FORMAT
es_formats.DATE_FORMAT
es_formats.SHORT_DATE_FORMAT
es_formats.DATE_INPUT_FORMATS
es_formats.THOUSAND_SEPARATOR
es_formats.DECIMAL_SEPARATOR
es_formats.TIME_FORMAT
es_formats.FIRST_DAY_OF_WEEK
es_formats.YEAR_MONTH_FORMAT
es_formats.MONTH_DAY_FORMAT
If you've tried gabriel's answer but it did not work, try to set USE_L10N = False in settings.py, it works for me.
Note that if USE_L10N is set to True, then the locale-dictated format has higher precedence and will be applied instead
See: https://docs.djangoproject.com/en/2.0/ref/settings/#std:setting-DATETIME_FORMAT
The accepted answer is correct, however I found it a bit confusing to understand how/why it works. Below is a small example that I hope illustrates how to do this more clearly.
Django provides a few ways to display "custom" fields in your admin view. The way I prefer to achieve this behavior is to define a custom field in the ModelAdmin class and display that instead of your intended field:
from django.contrib import admin
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=50)
birthday = models.DateField()
class PersonAdmin(admin.ModelAdmin):
#admin.display(description='Birthday')
def admin_birthday(self, obj):
return obj.birthday.strftime('%Y-%m-%d')
list_display = ('name', 'admin_birthday')
Notice that instead of displaying the actual birthday field from the Person model, we define a custom field (admin_birthday) as a method in the PersonAdmin and display that instead by adding it to the list_display attribute. Furthermore, the admin.display() decorator modifies how Django will display this custom field in the admin view. Using this approach, the admin panel will show the NAME and BIRTHDAY fields but using your preferred date formatting for the date.
The reason I prefer this approach is you keep the Model field definitions separate from how you display them in the admin panel. You can read more about alternative approaches in the Django admin documentation.