Replacing form view that appears elsewhere too in odoo 12 - python

By default, the create contact form from Contacts and create Vendor form from Purchase appears to have the same External ID ie, base.view_partner_form. I want to replace the form view for create contact. Now, i know that to replace a view i'll have to do this in my custom form view.
<field name="inherit_id" ref="external_id_of_form"/>
So how can i replace the form view in this case so that only the contact create form gets replaced? Can i replace the form view based on action? `

You're not "replacing" by inheriting, but changing/extending other views.
Indeed you should change the menu actions, because it is possible to set the target views.
But there is more than one approach. I'll try to list some of them, plus you can combine them.
full single views
one or more ir.ui.view of same type for the same model
can be referenced in actions and code
only one of them can be the default view of that type, which odoo will use for example in actions without a view reference, keep that in mind!
one base form with different extension views
one base view for a model
multiple primary extension views to that base view
you can either use those primary extensions as reference in actions
or you can set security groups in those extensions to show these extensions only to users of those groups
one view with extension views
that's the usual approach
you have a base view and lot of extensions
visibility is defined in the arch with groups, attrs, invisible, etc.
IMO the best approach for you is the first one. An Odoo example are the views for model account.invoice, because there are two form views: one for customer invoices and one for supplier invoices.

Related

Django: validation fails for many-to-many field with empty QueryDict as initial data

Setup:
Python 3.5.1 with Django 1.9.
I have a class-based generic view CreateRentView operating on the model Rent. I implemented a custom ModelForm RentForm to implement additional validations (e.g., ensure start_time <= end_time).
When creating a new Rent (via CreateRentView), first user defines start and end time. This triggers an AJAX request to get the available objects for this time frame and fills the rental_objects HTML widget using Javascript (see screenshot below).
Problem:
Everything is working fine (custom validation and AJAX communication), but when submitting the form I get a validation error for (many-to-many) field rental_objects: Select a valid choice. 1 is not one of the available choices.
Note: in the screenshot below, rental object MB1 was selected before submitting the form.
This is caused because I want to initialize the field rental_objects empty. Therefore, method get_form() of class CreateRentView sets form field rental_objects to an empty QuerySet:
def get_form(self):
form = super(generic.CreateView, self).get_form()
# Rental objects are retrieved via AJAX after start and end time is defined.
form.fields["rental_objects"].queryset = RentalObject.objects.none()
Obviously this triggers an internal Django validation that ensures that this field is submitted empty.
How can I avoid this validation?
PS: Of course, I could not override get_form() and empty the HTML widget for rental_objects using Javascript. But, this would be just a messy workaround
Django-AJAX-ManyToManyField:
I believe this is from your rental objects' choices.
If you use integers for your choices you should use IntegerField. For CharField use strings

Django admin: use checkboxes in list view in list_filter()

I have a model Transaction with a ForeignKey to another model (TransactionState) on state field. So in admin.py I have:
class TransactionAdmin(admin.ModelAdmin):
...
list_filter = ('state', )
...
In TransactionState I have records like "paid", "unpaid", "delivered", "canceled", Etc. and it works fine but I want to be able to filter using checkboxes to allow multiple selection like "paid" OR "delivered". It's possible?
For all models
You can easily override the django admin templates to customize the admin UI.
To edit the sidebar filter, just add a templates/admin/filter.html file, and write your custom HTML with radio buttons.
Note that this will change the sidebar filter for all models.
For a single model
If you want to change the filter for a single model, you can specify a template for a ListFilter:
class FilterWithCustomTemplate(admin.SimpleListFilter):
template = "custom_template.html"
Example
As a reference example, check is the default template for filter.html.
Radio buttons cannot have multiple selection, you would need to make them check boxes.
What you are looking for is making custom filters. I would suggest instead of overwriting the Filter List to contain a check form with check boxes, add a custom filter with each option as a filter. Use this link and scroll down to the SimpleListFilter and you will be able to code it with 5-10 LOC.

Django custom admin view like history

I need to add a custom view to a model admin similar to the history view. For example if I have a model called Job I can access the history by going to /jobs/job//history/. How do I add another view that will respond to a pattern like /jobs/job//workflow/?
You can define get_urls() on your Admin to add more admin views.
don't forget the admin_view() wrapper
if you wanted to add a view for an individual object (like the change form), just add the object id to your url pattern, then in your view (try to) grab the corresponding object.
It's up to you to provide the links (for example, by overriding the base (/change_form) template and adding a new item to the "object-tools" list).

Improving Performance of Django ForeignKey Fields in Admin

By default, Django's admin renders ForeignKey fields in admin as a select field, listing every record in the foreign table as an option. In one admin-accessible model, I'm referencing the User model as a ForeignKey, and since I have thousands of users Django is populating the select with thousands of options. This is causing the admin page to load incredibly slowly, and the select is not very useful since it can take a while to scroll through thousands of options to find the one you want.
What's the best way to change the rendering of this field in order to improve page load and usability? I'd like the select field to be replaced with some sort of button to launch a search form popup, or a text field that searches keywords via Ajax to find the Id for the specific User they want to associate. Does admin have anything like this builtin, or would I have to write this from scratch?
Add raw_id_fields to your model to only show the ID instead of a dropdown.
You're right, Cerin, the cause of the slowdown is because Django is populating the <select> element with too many options. You might want to use an autocomplete element instead.
Interestingly, Django 2.0 has introduced a new feature on the admin site, called autocomplete_fields, which I think you will find useful in this case. It uses AJAX.
class ExampleAdmin(models.ModelAdmin):
autocomplete_fields = ['example_field_user']
You can use one of the few autocomplete apps for Django. Check them at Django Packages.
There's also django-extensions that have ForeignKeyAutocompleteAdmin that fit your needs pretty well.
Another option is to add readonly_fields instead of raw_id_fields

Django best practice for displaying mostly read-only form, one field writeable

I have a requirement where one user creates an 'instance' of an object via a ModelForm. Another user of a different group has access to read all of the fields of the form, but has to update only one field. Think of a student who creates an exam object. Then a teach pulls up the exam and just needs to put in a grade, the rest of the exam is read only.
What's the best way to do that? Should I just query for the object, and display each field individually, then create a form (not a ModelForm?) for just the one field?
Should I just query for the object, and display each field individually, then create a form (not a ModelForm?) for just the one field?
This is probably the best way to go about it. Note you can use a ModelForm for the teacher form, see the Django documentation on using a subset of fields on a model form. You will have to display all the other fields manually in your template, but you should probably have a separate template for this view (I would use separate views as well).
You could find some code for a read only field on Django Snippets, but generally it's better to be explicit about what fields you are updating from each view. This is likely to be more trouble than it's worth.

Categories

Resources