How to sort column fields in Django model.object.values() - django

I am using this
objects = Model.objects.values('var1', 'var2', 'var4')
IN template i use
{% for fieldname in object.keys %}<th>{{ fieldname }}</th>{% endfor %}
But the field names appear in arbitrary order like
var4---var1----var2
I want them to appear like i provided in function
var1---var2----var4
is this possible

The easiest solution is to just use values_list, which returns tuples and change your template accordingly.
https://docs.djangoproject.com/en/1.3/ref/models/querysets/#django.db.models.query.QuerySet.values_list
If for whatever reason, you want to keep using dict-s, and want an "automagical" solution, you'd have to do quite a bit of work:
Subclass Django's ValuesQuerySet, name it for ex. OrderedValuesQueryset and change it's iterator method to use OrderedDict http://docs.python.org/dev/library/collections.html#collections.OrderedDict
Create a Queryset subclass which
in it's .values method returns an instance of
your OrderedValuesQuerySet
Create a custom models.Manager
class which in it's get_query_set
method uses your custom QuerySet
from 2.
Set the custom Manager to be used in your model. See https://docs.djangoproject.com/en/1.3/topics/db/managers/#custom-managers
Now what you are trying to do will work automatically on that model. You can also set the custom manager to a different attribute than objects, to also keep the default manager available.

The question is rather how to sort a Python dictionary, because this is what values() returns. Python dictionaries by definition do not have an ordering.
See this blog post

Related

Django: creating graphs in admin Inlines

I'm working in the admin interface, and I'm trying to create a InlineModelAdmin subclass that given a model will just give me certain values from related values (say, date and value fields) and use them in a subclassed template to build a graph.
Problem is: I don't know what to subclass in the inline!. The inline_admin_formset seems to have the form already cooked and I can't access the date. get_form I can't get to send the data I want to the template. I tried change_view to put the data as extra_context, but it's only called for the parent class. And so on.
Can anyone orient me as to where would be the best place to work?.
I know this would be a lot easier in a custom view, but the high command is adamant that this has to be done in the admin interface.
Thank you!
Looks like I managed to access the raw data from the inline objects using the following code in the template:
<script>
var data = google.visualization.arrayToDataTable([
["Date", "Value"],
{% for form in inline_admin_formset %}
["{{form.original.date}}", {{form.original.value}}],
{% endfor %}
]);
</script>
So it looks like now I only need to parameterize what fields the graph is going to plot from the inline, or from the object (date and value in this case). Perhaps add a graph_fields() method to both.
In any case, thanks to whoever gave this a thought.

Database localization in Django

I am using .mo files for localization in Django.
Also, in my database, I store some translated text in different fields, such as:
name_en, name_es, name_de (they are all columns in each row).
What will be the best method to choose the correct field inside a template?
i.e.:
{{ name.some_method }} will generate the correct translation based on the current localization.
Thanks,
Meit
You should look at http://goodcode.io/articles/django-multilanguage/ Here’s a simple solution that may fit your use case and is easy to implement and understand.
You should look at Django Transmeta, it work the same way as what you've done (DB fields with language code) but it's a more complete solution. It already deal with the template stuff, etc.
You can check Model Internationalization and Django Packages for more info and ideas in this domain.
I can see two method for doing this, one in your view and the other one is in the template...
In view:
Probably you keep the user language information somewhere so,
user_lang = 'es'
obj = Somemodel.objects.get(pk=123434)
obj.local_name = getattr(obj, 'name_%s'%user_lang)
So, you keep local translation in a specific variable of the instance and in your template you can use is as:
{{obj.local_name}}
But that might be costly if you wish to pass the template a queryset instead of a single instance. For a such usege you have to evaluate that value for each object in your queryset.
In template:
That is a more complex way of solving the porblem in the template...
Define a template tag and pass object_id, and local language information and get the translated text using a similar getattr function. But in that point, if you wish to use this for more than one model, you probably have to pass a content type information for your template tag too, such as:
{% get_translation <object_id> <content_type_id> <local_language> %}
And in your template tag function, do something like:
from django.contrib.contenttypes.models import ContentType
....
cont_obj = Content_type.objects.get_for_id(<cotent_type_id>) #get the related model
obj = cont_obj.get_object_for_this_type(pk=<object_id>) # get your object
return getattr(obj, 'name_%s'%<local_language>)

Returning values from methods in Django

So, time for a newbie question but so utterly important since the documentation seems to have missed this very very basic example.
All I'm trying to do is to return a value from a model to a view in Django. Here is some code.
The model
class Page(models.Model):
def index(self):
ex = 'foo string'
return ex
The view
def index(request):
start = Page.objects.all().index
#start = Page.index
return render_to_response('index.html', {'page_content': start})
And, nothing gets rendered. I get this error message with <unbound method Page.index>
...
The funny thing is that if I skip the functions and so on and creates the model like this
class Page(models.Model):
ex = 'goo string'
And call it with
start = Page.ex
Everything renders out fine.
Any pointer or working example would be much appreciated!
Thanks
This sort of thing is rightly left out of the Django tutorial, since it has nothing to do with Django. If you don't know basic Python, then you need to follow a Python tutorial.
The main thing wrong with the code you gave is that you haven't actually called the index method, you've just referred to it. In Python, as in many other languages, to call a method you need to use method(). So you need:
Page.objects.all()[0].index()
Page.objects.all()
returns you a query set of Page objects, not a single Page object. You can call Page.objects.all()[0].index.
To render it right, I believe you should pass Page.objects.all() to the template and then iterate over it in the template, like this:
{% for page in page_content %}
{{ page.index }}
{% endfor %}
If you define an attribute like this:
class Page:
ex = 'some char'
then you are creating class attribute, which can be accessed in a class and in every instance of that class (it is shared by all those objects). This is not an instance attribute.
In Django you have two types of custom database objects methods: row (or instance) based methods, table based methods.
Row based methods:
You just define a method in the model class like you did:
class Page(models.Model):
def row_method(self):
return "Row method working on Page object with id " + str(self.id)
This methods are meant to be called from a single Page object!
So you can do: Page.objects.all()[0].row_method(), but you can NOT do Pages.objects.all().row_method because Pages.objects.all() returns an array of Page objects for which the row_method() method is not defined.
These methods are row based because they act at row level (a single row in the DB table and so a single instance of the relative model class).
Table based methods:
You can also define methods related to a specific model type and not to a specific instance using Managers. You can find documentation about Manager here: http://docs.djangoproject.com/en/1.2/topics/db/managers/
These type of methods are available when managing a collection of Page objects, for example you could write:
Page.objects.filter(title__startswith='The').calculate_total_title_length()
In this case the method has access to the collection of Page objects returned from the query and, in my example, it calculates the sum of all the titles length of all the Page objects found by the query.

django pagination: How to get number of page by id of element in the list

I use django-paginaton app and I'm very glad to use it. Now I need feature, that I don't know how to implement. I have list of elements, that paginated by django's paginator. I have one element with specified id, that I should show, but I don't know what page contains it. I need mechanism jump to the page, that contains my element.
I think it's a good idea if django-pagination will support this transparently and automatically. For example, I set special context variable page_by_id to X and if page is None, it will be defined to the value, that contains my X element.
What do you think about this mechanism?
May be there is another clean way to do this?
This is for continue of this questions:
Django pagination and "current page"
Django Pagination - Redirecting to the page an object is on
At least, I wrote patch for django-pagination that provide 2 features:
Get number of page by id of element inside paginated list;
Possibility to rename default parameter 'page' to another value for
using it inside template;
This works transparently by adding 2
optional parameters in autopaginate templatetag:
{% autopaginate object_list paginated_by orphans page_by_id parameter_name %}

Filtering models with inheritance in Django

I have two Django model classes that are structured similar to the following:
class Build(models.Model):
project = models.CharField(max_length=100)
...
class CustomBuild(Build):
custom_type = ...
...
I want to select all Builds and CustomBuilds (each CustomBuild has a one-to-one relationship with a Build) from the database with a specific project attribute.
I believe Build.objects.filter(project="myproject") will select the correct objects but many of them will be missing the additional data (such as custom_type) that would be provided by a CustomBuild object. On the other hand, filtering CustomBuild.objects will exclude those objects that are not CustomBuilds.
How can I accomplish this? Thanks.
There are a couple approaches you can take to handling the QuerySets of "mixed models" that you obtain when you perform this kind of query. A lot of it depends on your ultimate goal.
The "simple and dumb" way, which I use a lot, is to manage the results with utility functions. If you plan to process the result of Build.objects.filter(project="myproject") in a template, for example, you could use custom template tags or filters to take special action. Assume in the below code build_objects contains the result of your filter():
{% for build in build_objects %}
{% if build|is_custom_build %}
<p>This is a custom build of custom type {{ build.custom_build.custom_type }}!</p>
{% endif %}
<p>This is a custom build OR a standard build</p>
{% endfor %}
The obvious problem here is if you have numerous subclasses, writing template filters may be impractical or grow tedious. However, in my experience I usually have a half-dozen subclasses at most so this is not always a problem.
You could also write a parameterized filter like so:
{% if build|is_of_buildtype:"custom_build" %}
With the filter code as follows:
def is_of_buildtype_filter(value, arg):
if hasattr(value, arg): return True
else: return False
This filter simply checks for the presence of the argument as an attribute on the build object (passed in as value). The argument string should be the name of the automatically generated OneToOneField that you want to detect, in this case custom_build.
For view code, similar sorts of helper functions would work the same way but are even easier because you don't need to write custom filters or tags.
This approach works in many cases, but there are more complicated scenarios where it might not be practical. Unfortunately, Django cannot natively provide you with a QuerySet that contains subclass instances when you perform operations on the base class (ie. a QuerySet that truly contains "mixed models"). You may require this in situations where processing the results with helper functions is not possible.
I personally avoid these situations entirely, usually by rethinking my model design. But if that's not possible, there are many interesting attempts at solutions, like this Inheritance MixIn. There are also several Django snippets on the subject. Be aware, though, that almost any solution like this will be performance-limited.
You can fetch Build objects with Build.objects.filter() and access the subclass when you need to:
qs = Build.objects.all()
build_obj = qs[4]
custom_build_obj = build_obj.custom_build
custom_build_obj.custom_type = ...