Handling two Django models in a single POST

There are times when, you want to handle multiple Django models in a single POST request (By this i meant data posted from html form/ template contains data of two different Django models). I was struggling with this few months back and got a fantastic reference link from #django on IRC.

You can use the below method as a simple example, here’s a view that updates a User and their Profile in one view:

def user_edit(request):
    if request.method == 'POST':
        user_form = UserForm(request.POST, instance=request.user)
        profile_form = ProfileForm(request.POST, instance=request.user.profile)

        if all([user_form.is_valid(), profile_form.is_valid()]):
            user = user_form.save()
            profile = profile_form.save()
            return redirect(user)
    else:
        user_form = UserForm(instance=request.user)
        profile_form = ProfileForm(instance=request.user.profile)

    return render(request, 'user_form.html', {
            'user_form': user_form,
            'profile_form': profile_form,
            })

The two most important things to notice here are:

a. The use of all() instead of user_form.is_valid() and profile_form.is_valid().

This is because Python will skip the if clause if the first form is not valid, and so it won’t run validation on the second form. If some error is present in second from user will again get the error second time. using all() runs validation on all the submitted forms thus you get the errors at one time.

b. Two forms in the context.

Just render them all inside the one <form> tag, and it will be fine. If any of the field names clash, pass a prefix= when constructing one of the forms, to prefix its field names so they’re unique.

Related blogs :

  1. Django – AttributeError: ‘Http404’ object has no attribute ‘status_code’
  2. Make primary key with two or more field in Django

‘ascii’ codec can’t encode characters : ordinal not in range(128)

I work on a system which fetches data from a database (Postgres) using python & writes them into a csv file. Few days ago i came through an error which was showing “ascii codec can’t encode characters : ordinal not in range(128)” whenever i tried to fetch data from a particular date range.

Problem : 

When ever i tried to fetch data of a particular data range (suppose date range between 1-Jan-2013 to 31-Jan-2013) error popped up. although data fetching between other data range was working fine. That clearly meant that problem was in data of that date range only. Actually problem was in few entry of one of the column(s) (email) of my table, which was storing some Non-ASCII value . When python tried to write that value into the csv, it couldn’t process the value & error came up.

Solution :

Either you can make that value (data) unicode in python by  using:

email = [DefectedValue].encode('utf-8').strip()

Or you can find the data actually causing problems and remove them. for finding the defected data you can run following command in your PostgreSQL terminal.

SELECT * FROM YourTableName WHERE EffectedColumn similar to '%[^\x20-\x7e]+%' ;

You can update/delete that tuple which is storing Non-ASCII characters.

Make primary key with two or more field in Django

Most of the time, people don’t actually need their composite (multi-column) key to be the primary key.

Django operates best with surrogate keys –  that is, it automatically defines an autoincrement field called id and sets that to be the primary key. That is suitable for almost all the users.

If you then need to enforce a unique constraint on your model across two or more fields, you can use the unique_together setting in the inner Meta class.

class Student(models.Model):
    Name = models.CharField(max_length=100)
    Roll = models.CharField(max_length=20)
    Department = models.CharField(max_length=15)

    class Meta:
        unique_together = (('Roll', 'Department'),)

It would act as a surrogate primary key column.

Sets of field names that, taken together, must be unique:

unique_together = (('Roll', 'Department'),)

This is a tuple of tuples that must be unique when considered together. It’s used in the Django admin and is enforced at the database level (i.e., the appropriate UNIQUE statements are included in the CREATE TABLE statement).

For convenience, unique_together can be a single tuple when dealing with a single set of fields :

unique_together = ('Roll', 'Department')

Python Decorators

Python Conquers The Universe

In August 2009, I wrote a post titled Introduction to Python Decorators. It was an attempt to explain Python decorators in a way that I (and I hoped, others) could grok.

Recently I had occasion to re-read that post. It wasn’t a pleasant experience ? it was pretty clear to me that the attempt had failed.

That failure ? and two other things ? have prompted me to try again.

  • Matt Harrison has published an excellent e-book Guide to: Learning Python Decorators.
  • I now have a theory about why most explanations of decorators (mine included) fail, and some ideas about how better to structure an introduction to decorators.

There is an old saying to the effect that “Every stick has two ends, one by which it may be picked up, and one by which it may not.” I believe that most explanations of decorators fail because they pick…

View original post 1,457 more words