Saturday, May 28, 2011

Dynamic Initial Value for Django Admin Inline Form

I am impressed with Django Admin Inline Form. Even more impressed by the simplicity to set the initial value for it.

One can easily set the initial value for Django Admin Add Form, via url get parameter. For example: http://localhost:8080/admin/myapp/mytable/?myfield_id=1

This will not work if myfield is within the inline form, instead of regular form. To do that, override admin.TabularInline formfield_for_foreignkey method.

Here is an example:

class MyTabInline(admin.TabularInline):
    model = models.MyModel
    extra = 1

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == 'myfield':
            kwargs['initial'] = request.GET.get('myfield_id', '')
        return super(MyTabInline, self). 
                formfield_for_foreignkey(db_field, request, **kwargs)
Pretty simple.

Friday, May 27, 2011

Perform Extra Operations after Saving All Inlines in Django Admin

Django Admin provides quite solid foundation for performing CRUD operations. Djando Admin does most things already.
What I needed to do this time is to perform extra operations after saving all inlines in Django Admin. If I do not need to access request object, I could perform extra operations by overriding save method. The thing is I need to get current logged in user, that is exactly why I need to do it from admin.ModelAdmin.

First attempt is by overriding admin.ModelAdmin save_model method. Failed, due to after performing obj.save(), the inline data are not yet available.

What next? Fortunately, I found helpful information from this link.

From that, we could intercept right before preparing the response.
There are three methods which related with setting up response:
response_add, response_change, response_action.

Here is an example of overriding response_add method.
def response_add(self, request, new_object):
    # Perform extra operation after all inlines are saved
    return super(AdminSubClass, self).response_add(request, new_object)

There is a ticket with this issue.
Hopefully there will be even better way to perform such action.

Friday, May 20, 2011

Remove First N bytes From a (Binary) File

Situation:
You have a (binary) file, and you need to remove the first n bytes of data in it.

Solution:
Use dd. Read more about it, here.

Here is how to do it:
$ dd if=input_file ibs=1 skip=N of=output_file

N is the number of bytes to be removed.

example:
$ dd if=input_file.dat ibs=1 skip=3 obs=10M of=output_file.dat


Now, what if you need to remove the first N bytes and the last M bytes from a file?
$ dd if=input_file.dat ibs=1 skip=N count=X of=output_file.dat

To calculate X:
X = acutal_file_size_in_bytes - N - M


I recommend you to read through the man pages, and play around with ibs, obs, bs, count values and other parameters that might be useful.

Thursday, May 19, 2011

Python ValueError Bad Marshal Data

I encountered this problem when I copied my django project along with (cherrypy's) wsgiserver and started it.

To solve this issue, I needed to remove wsgiserver.pyc, and re-run the program. Just like that.

So, it is a good idea to clean all the *.pyc's, when moving/copying codes in a different computer, and let python recreated them all.