Django ModelAdmin queryset override doesn't work - django-admin

I'm trying to override the queryset() of a ModelAdmin class so that the list of objects shown in admin would be sorted by two levels.
I've tried the following code, but it does not work, i.e. the table is not sorted as expected
class ProductAdmin(admin.ModelAdmin):
def queryset(self, request):
qs = super(ProductAdmin, self).queryset(request)
return qs.order_by('category','market')
list_display = ('category', 'market', 'name', 'quantity')
admin.site.register(Product, ProductAdmin)
btw, you can't use ordering = ('category','market') as django specifically states that only the first item in the ordering tuple takes effect (see note in the documentation here)

get_queryset works in Django 1.8.

I had this exactly problem. Here's what I did:
I subclassed ChangeList and overrode ChangeList.get_query_set to redo the correct order_by that was previously changed by ChangeList.get_ordering:
This is what I did in my case (I'm using django-easytree, but the same applies for django-mptt):
class MyChangeList(ChangeList):
def get_query_set(self):
qs = super(MyChangeList, self).get_query_set()
return qs.order_by('tree_id', 'lft')
Also, check these tickets:
"NFA: Don't override order_by if no default ordering is specified"
"Admin ChangeList doesn't apply 'order_by' clause specified by ModelAdmin.queryset"

The release notes for Django 1.4 say that Django now supports Multiple sort in admin interface:
The admin change list now supports sorting on multiple columns. It
respects all elements of the ordering attribute, and sorting on
multiple columns by clicking on headers is designed to mimic the
behavior of desktop GUIs.
And from ModelAdmin ordering:
Set ordering to specify how lists of objects should be ordered in the
Django admin views. This should be a list or tuple in the same format
as a model's ordering parameter. [...] Django honors all elements in the list/tuple; before 1.4, only the first was respected.
On a semi-related note - if you do override queryset to provide a custom sort order, it seems that the Changelist will override that sort order. It applies any sorting found in the ordering parameter, and if there isn't one, it applies a default sort by pk, thus negating any sorting you did in queryset.
I think it's supposed to work - at least this Django Ticket says fixed. But I was just trying to apply a custom sort using queryset a few days ago, and it didn't work at all for me. Even sorting on a single field, seemed to be overridden in the final view. So either I did something wrong, or it's not all that fixed. :)
Note that it is possible to do a custom sort via code, but you have to subclass Changelist, and override its get_query_set() method, as per this snippet. (Although this is overkill, if you only need multiple fields sorted, since Django 1.4 now supports multiple fields).

Related

Vaadin 14 TreeGrid - Cannot add the same item multiple times

Working on a project that will display hierarchies of "tasks". I'm running into a problem where it will not allow for multiple entries of the same object. From what I can tell, the "duplicate" item is under a different parent.
The domain data allows for this - a given task may appear in lots of places.
It would seem that this is intentional (maybe), but is there a way around this?
It's intentional to a degree; each Grid and TreeGrid data item is expected to be unique. You could work around this by creating your own implementation of the hierarchical DataProvider class (for example extend AbstractHierarchicalDataProvider) which overrides the getId method along with the other required methods. The return value of this method needs to be unique per item, as it's used as a hash key.
Well, this is probably not the best solution, but it works.
I added a field to the abstract super class that is initialized with the current time (long ms). When I am adding items to the tree grid, I check to see if the tree contains the item and if so, I randomize the field and then add it. The new field is marked #Transient so it's not persisted.

Grails- how to get part of the values in set collection?

I have a domain which call party and has many invitees.
party.invitees give me a the set collection of the invitees.
I want to get only some of the invitees so I try do do the followinf in my service.
partInvitees= event?.invitees?.findAll{[offset: 3,max: 8]}
It doesn't give the correct result. It gives me all the invitees instead only the specific I have asked.
The findAll method you are invoking in there is not from GORM, but from Groovy Collections. So even if you paginate it (which is not possible directly in Groovy, AFAIK), you'll be bringing the whole collection into memory. If you don't mind, just do:
event?.invitees[offset..(offset-1)+max]
If the collection is too big and you don't want to bring it to memory, you can also query the Invitee directly:
Invitee.findAllByEvent(event, [offset: 3,max: 8])
But be aware that the order won't be necessarily the same, since Gorms' findAllBy doesn't know about the collection index (I'm assuming invitees is a list). You can make the collection index-aware, but it's a bit tricky.
You could use the GORM list() method to get the entire collection for a domain class. If you want only a subset of the collection you could use list() with some parameters.
If your domain class is named Invite, you should use Invite.list(max: 8, offset: 3, sort: "id", order: "asc") to get the subset described in your question. Keep in mind that different sort/order params could give you different results.
See the list() or listOrderBy() documentation for more information.
If you want Invites only for a specific Event you should read the Deigote answer.

Polymorphic inline model forms in django

I have a Person model which has many Animal models as pets. Dog is an Animal with a "favorite bone" field, and Cat is an Animal with a "likes catnip?" field and a "favorite fish" field.
#models
class Person(db.model):
pass
class Animal(db.model):
models.ForeignKey(Person) #owner
name = CharField()
class Dog(Animal):
favorite_bone = CharField()
class Cat(Animal):
favorite_fish = CharField()
likes_catnip = BooleanField()
I would like to inline edit all of a Persons pets, in the Person admin form however, I've read that Django inline admin forms don't support polymorphic inline forms[1], in that, you will only get the parent class fields (e.g. not the favorite_bone or favorite_fish and likes_catnip fields.
Where does this problem come from?
What changes could be made to the framework to accommodate this?
If these changes should not be made, why not?
[1] http://www.mail-archive.com/django-users#googlegroups.com/msg66410.html
(This is an old question, but I thought I'd add an answer in case it is still useful. I've been working on a similar question recently.)
I believe it would be challenging to change Django form-generation to do what you want. The reason is that the inline formset uses a single class/form for all rows of the inline -- there are no configuration options that are evaluated per-row of the inline form. I have convinced myself of this by reading the code itself --- look for "inline" and "formset" in django.contrib.admin.options.py, especially lines 1039-1047 (version 1.5.1). This is also the reason why you can't have some fields read-only in existing items and changeable in new items (see this SO question, for example).
The workarounds found for the readonly case have involved a custom widget that produces the desired behavior such as this one. That still won't directly support polymorphism, however. I think you would need to end up mapping your divergent types back to a common ancestor (e.g. have all pet classes able to return a dict of their unique attributes and values), and then create a single custom widget that renders out the polymorphic part for you. You'd then have to map the values back on save.
This might be more challenging than it is worth, and may lead back to the suggestion in the other answer to not use admin for this :-)
may have a look here.
but i think the modeladmin is currently not able todo such things.
you are able to create a custom edit view for your model...
there is almost everything possible.
It may be possible to do this with Generic Relations.

add user define properties to a domain class

i have a requirement to allow the user to define some custom field in one of the system entities. do you have any suggestion/pattern/plugin that will help me add this feature to my application.
thanks,
Meni
You can add a Map property to your domain class and store arbitrary data there. It's rather limited though. It will generate a table with varchar(255) keys and values, so you need to manage any type conversions yourself, e.g.
class Thing {
String name
Map extraProperties = [:]
}
int age = 123
def thing = new Thing(name: 'whatever')
thing.extraProperties.age = age.toString()
thing.save()
...
def thing = Thing.get(thingId)
int age = thing.extraProperties.age.toInteger()
See section "5.2.4 Sets, Lists and Maps" at http://grails.org/doc/latest/ for the brief online docs.
Sounds like you want your application to be an infinitely adjustable wrench that users can modify at will. Is that fair?
I don't think it's possible or desirable. Think about what happens when you add an attribute to an existing domain object in Grails. The attribute is added to the ORM mapping, which means the tables have to be modified. The UI has another text box added for data entry; the list page has another column added to its table.
There's a lot going on when you add an attribute. How will you manage multiple users modifying the app all at the same time? What happens when one user is modifying a table while another is accessing the old version?
You ask too much. I don't think it's a reasonable requirement. Grails' sweet spot is rapid development of web-based CRUD applications. I don't think that includes modification by users at runtime.

How can I modify the queryset in the change list view depending on a parameter I set in the URL

My problem is the following and it is related to the change list view of the admin interface.
I have a workorder model with several fields to caracterize the work order.
They are : type, nature, scheduling_type (and others).
When I see the list view, I would like to be able to change the filter (thus be able to create complex ones depending on the values of the different fields of the workorder model - the ones above and dates for example).
I have found post showing how to modify the default queryset (using managers for example) but I can't find a post that will use a value that is given in the url (ex. admin/workorder/planned_corrective). When the parameter planned_corrective is found, it must be used to select the appropriate queryset or manager and render the corresponding list.
As a add on, I want from that list to be able to use the standard admin options (like list filters, search ...) on that query.
Hope it is clear and thanks in advance for your help.
It sounds like you're after a RESTful interface.
You could accomplish much of this just by being clever with your urls.py - ie, defining admin/workoder/planned_corrective and every other possible parameter that could be encoded in the URL.
A lot of this can also be accomplished just by adding a get-absolute-url method to your models.
Or, you could the effort into using something like the django-rest-interface in your app.

Resources