Best django questions in June 2011

How to create a thread-safe singleton in python

13 votes

I would like to hold running threads in my Django application. Since I cannot do so in the model or in the session, I thought of holding them in a singleton. I've been checking this out for a while and haven't really found a good how-to for this.

Does anyone know how to create a thread-safe singleton in python?

EDIT:

More specifically what I wand to do is I want to implement some kind of "anytime algorithm", i.e. when a user presses a button, a response returned and a new computation begins (a new thread). I want this thread to run until the user presses the button again, and then my app will return the best solution it managed to find. to do that, i need to save somewhere the thread object - i thought of storing them in the session, what apparently i cannot do.

The bottom line is - i have a FAT computation i want to do on the server side, in different threads, while the user is using my site.

Unless you have a very good reason - you should execute the long running threads in a different process altogether, and use Celery to execute them:

Celery is an open source asynchronous task queue/job queue based on distributed message passing. It is focused on real-time operation, but supports scheduling as well.

The execution units, called tasks, are executed concurrently on one or more worker nodes using multiprocessing, Eventlet or gevent. Tasks can execute asynchronously (in the background) or synchronously (wait until ready).

Celery guide for djangonauts: http://django-celery.readthedocs.org/en/latest/getting-started/first-steps-with-django.html

For singletons and sharing data between tasks/threads, again, unless you have a good reason, you should use the db layer (aka, models) with some caution regarding db locks and refreshing stale data.

Update: regarding your use case, define a Computation model, with a status field. When a user starts a computation, an instance is created, and a task will start to run. The task will monitor the status field (check db once in a while). When a user clicks the button again, a view will change the status to user requested to stop, causing the task to terminate.

Authorization in social networking website

10 votes

I need to accomplish the following related to privileges:

I have 3 users:

- User A
- User B
- User C

Each of the users has the following documents with associated access settings:

- User A
    - Document A1, only allow contacts to view
    - Document A2, allow everyone to view
    - Document A3, allow no one to view except myself
    - Document A4, allow contacts, and contacts of contacts to view
- User B
    - Documents B1, B2, B3, B4 with similar privileges
- User C
    - Documents C1, C2, C3, C4 with similar privileges

User A has User B as a contact but is not a contact of User C (User B and User C are contacts).

Thus, User A would be able to view the following:

- Document B1 (contacts can view)
- Document B2 (everyone can view) 
- Document B4 (contacts of contacts)
- Document C2 (everyone can view)
- Document C4 (contacts of contacts)

Could someone please explain how these privileges would be handled. And if you could link me to any documentation or articles that would help me hit the ground running. Thank you.

A general answer is to find the distance between the document owner and a given contact. In Computer Science terms, this is a directed graph.

There's a good article with some SQL queries that covers this topic at http://techportal.ibuildings.com/2009/09/07/graphs-in-the-database-sql-meets-social-networks/. Rather than trying to summarize the entire article, here's how to conceptualize the problem:

  • Start with a blank piece of paper.
  • Draw a dot somewhere on the page for each person (in this case, Users A, B, and C). In CS terms, this is a "node".
  • Draw an arrow from a user to all of their contacts. In CS terms, this is a "directed edge", or an "arc".
    • This isn't explicit in the question, but it looks like User C must be a contact of User B, or a contact another of User A's other contacts (since User A can read C2 and C4).
    • So in this case, you would draw from User A -> User B, and User B -> User C.

As an aside, if being a "contact" is mutual, you can draw a line segment (or bidirectional arrow) instead of an arrow. In CS terms, this would be an "undirected" vs. a "directed" graph. Facebook relationships are an undirected relationship; if someone is my friend, then I am also their friend. By contrast, if someone is in my Outlook address book, I'm not necessarily in theirs. So this is a directed relationship.

As more users are added to the drawing, you'll notice that a user's contacts are one step away, and their contacts-of-contacts are two steps away. But you can only travel in the direction of the arrow.

So the problem for contacts is, "How do I find all nodes whose graph distance is one?" And the question for contacts-of-contacts is, "How do I find all nodes whose graph distance is two?". Although "two or less" is probably more appropriate, since you'd expect direct contacts to have access to all of the "contacts-of-contacts" content.

For the general case, there are some SQL queries described in the article that might provide some insight. But for your specific need, I'd consider just using some joins.

Let's consider a Users table, with primary key id along with its other fields, and a HasContact table which has only two columns: userId and contactId. We'll assume that User A has id 1, User B is 2, and User C is 3. HasContact has rows (1, 2) and (2, 3) to represent the relationships described above.

A pretty simple set of SQL joins can produce a list of all friends, or all friends-of-friends.

The following query would return all IDs of a User's contacts:

SELECT contact.id
  FROM Users "user"
    LEFT JOIN Relationships "rel"
      ON user.id = rel.userid
    LEFT JOIN Users "contact"
      ON rel.contactId = contact.id
  WHERE user.id = $id_of_current_user

If you know the user IDs, an authorization query could be quite simple:

SELECT count(*)
  FROM Relationships "rel"
  WHERE rel.userid = $document_owner_user_id
    AND rel.contactid = $id_of_current_user

If the query returns 0, then we know that the current user is not one of the document owner's contacts.

We can update that second query to indicate whether a user is a contact-of-a-contact:

SELECT count(*)
  FROM Relationships "rel_1"
    INNER JOIN Relationships "rel_2"
      ON rel_1.contactId = rel_2.userId
  WHERE rel_1.userid = $document_owner_user_id
    AND rel_2.contactid = $id_of_current_user

This should return nonzero, as long as there are entries in the Relationships table such that ($document_owner_user_id, X) and (X, $id_of_current_user) both exist. Otherwise, it will return zero.

I know this is a long and somewhat indirect answer, so please comment if you have any questions.

Improving Python/django view code

7 votes

I am very new to Python/Django and programming in general. With the limited tools in my programming bag, I have written three views functions for after a user registers: it allows the user to add information and upload a thumbnail before activating his account.

I have posted the code that I have written so far so that someone with far more experience than I have can show me how to improve the code. No doubt this is crude code with all the marks of a novice, but I learn best from writing code -- seeing ways to improve it and learning new tools -- and rewriting it.

I know that the answer to this question will take a considerable amount of time. Therefore, I will be awarding a 200 point bounty to this question. SO will only allow me to add a bounty two days after a question has been posted, so I will be adding a bounty to this question on Tuesday (as soon as it's available to add). Please note that since I won't be selecting an answer until after I have posted a bounty, answers that are provided before the bounty has been added will still be 'as if' there is a bounty on the question

The following is my self-commented code. In particular, I have a lot of boilerplate code for the first 10-14 lines of each function to redirect a user based upon whether he is logged in, if he has already filled out this info, if he has session info, etc.

# in model.py
choices = ([(x,str(x)) for x in range(1970,2015)])
choices.reverse()

class UserProfile(models.Model):
    """
    Fields are user, network, location, graduation, headline, and position.
    user is a ForeignKey, unique = True (OneToOne). network is a ForeignKey.
    loation, graduation, headline, and position are optional.
    """
    user = models.ForeignKey(User, unique=True)
    network = models.ForeignKey(Network)
    location = models.CharField(max_length=100, blank=True)
    graduation = models.CharField(max_length=100, blank=True, choices=choices)
    headline = models.CharField(max_length=100, blank=True)
    positions = models.ManyToManyField(Position, blank=True)
    avatar = models.ImageField(upload_to='images/%Y/%m/%d', blank=True, default='default_profile_picture.jpg')
    # if the user has already filled out the 'getting started info', set boolean=True
    getting_started_boolean = models.BooleanField(default=False) 

General context: after a user has registered, I am giving them two session variables:

    request.session['location'] = get_location_function(request)
    request.session['username'] = new_user   # this is an email address

After a user has registered, they are re-directed to the getting_started pages.

First page:

# in views.py

def getting_started_info(request, positions=[]):
    """
    This is the first of two pages for the user to
    add additional info after they have registrered.
    There is no auto log-in after the user registers,
    so the individiaul is an 'inactive user' until he
    clicks the activation link in his email.
    """
    location = request.session.get('location')
    if request.user.is_authenticated():
        username = request.user.username        # first see if the user is logged in
        user = User.objects.get(email=username) # if so, get the user object
        if user.get_profile().getting_started_boolean: 
             return redirect('/home/')                       # redirect to User home if user has already filled out  page
        else:
            pass
    else:                                                   
        username = request.session.get('username', False)    # if not logged in, see if session info exists from registration
        if not username:
            return redirect('/account/login')                # if no session info, redirect to login page
        else:
            user = User.objects.get(email=username)
    if request.method == 'POST':
          if 'Next Step' in request.POST.values():      # do custom processing on this form
              profile = UserProfile.objects.get(user=user)
              profile.location = request.POST.get('location')
              populate_positions = []
              for position in positions:
                  populate_positions.append(Position.objects.get(label=position))
              profile.positions = request.POST.get('position')
              profile.headline = request.POST.get('headline') 
              profile.graduation = request.POST.get('graduation') 
              profile.save()
              return redirect('/account/gettingstarted/add_pic/')         
    else:
        form = GettingStartedForm(initial={'location': location})
    return render_to_response('registration/getting_started_info1.html', {'form':form, 'positions': positions,}, context_instance=RequestContext(request))

Second page:

def getting_started_pic(request):
    """
    Second page of user entering info before first login.
    This is where a user uploads a photo.
    After this page has been finished, set getting_started_boolean = True,
    so user will be redirected if hits this page again.
    """
    if request.user.is_authenticated():
        username = request.user.username                      
        user = User.objects.get(email=username)            
        if user.get_profile().getting_started_boolean: 
             return redirect('/home/')                      
        else:
            pass
    else:                                                   
        username = request.session.get('username', False)    
        if not username:
            return redirect('/account/login')                
        else:
            user = User.objects.get(email=username)
    try:
        profile = UserProfile.objects.get(user=User.objects.get(email=username)) # get the profile to display the user's picture
    except UserProfile.DoesNotExist:        # if no profile exists, redirect to login 
        return redirect('/account/login')   # this is a repetition of "return redirect('/account/login/')" above
    if request.method == 'POST':
        if 'upload' in request.POST.keys():
            form = ProfilePictureForm(request.POST, request.FILES, instance = profile)
            if form.is_valid():
                if UserProfile.objects.get(user=user).avatar != 'default_profile_picture.jpg': # if the user has an old avatar image
                    UserProfile.objects.get(user=user).avatar.delete()   # delete the image file unless it is the default image
                object = form.save(commit=False)
                try:
                    t = handle_uploaded_image(request.FILES['avatar']) # do processing on the image to make a thumbnail
                    object.avatar.save(t[0],t[1])
                except KeyError:
                    object.save()
                return render_to_response('registration/getting_started_pic.html', {'form': form, 'profile': profile,}, context_instance=RequestContext(request))
        if 'finish' in request.POST.keys():
            UserProfile.objects.filter(user=user).update(getting_started_boolean='True') # now add boolean = True so the user won't hit this page again
            return redirect('/account/gettingstarted/check_email/')       
    else:
        form = ProfilePictureForm()
    return render_to_response('registration/getting_started_pic.html', {'form': form, 'profile': profile,}, context_instance=RequestContext(request))

Third page:

def check_email(request):
    """
    End of getting started. Will redirect to user home
    if activation link has been clicked. Otherwise, will
    allow user to have activation link re-sent.
    """
    if request.user.is_authenticated():    # if the user has already clicked his activation link, redirect to User home
        return redirect('/home/')
    else:                                  # if the user is not logged in, load this page
        resend_msg=''
        user = email = request.session.get('username')
        if not email:
            return redirect('/account/login/')
        if Site._meta.installed:
            site = Site.objects.get_current()
        else:
            site = RequestSite(request)
        if request.method == 'POST':
            RegistrationProfile.objects.resend_activation(email, site)
            resend_msg = 'An activation email has been resent to %s' %(email)
            return render_to_response('registration/getting_started_check_email.html', {'email':email, 'resend_msg':resend_msg}, context_instance=RequestContext(request))
        return render_to_response('registration/getting_started_check_email.html', {'email':email, 'resend_msg':resend_msg}, context_instance=RequestContext(request))

I originally tried to replicate the behaviour of your signup process using django.contrib.formtools.wizard, but it was becoming far too complicated, considering there are only two steps in your process, and one of them is simply selecting an image. I would highly advise looking at a form-wizard solution if you intend to keep the multi-step signup process though. It will mean the infrastructure takes care of carrying state across requests, and all you need to do is define a series of forms.

Anyway, I've opted to simplify your whole process to one step. Using a basic model form, we are able to simply capture ALL of the UserProfile information you need on one page, with very very little code.

I've also gone with class-based-views, introduced in Django 1.3. It makes boilerplate code (such as your check at the top of each function for what process you're up to) much nicer to manage, at the cost of more upfront complexity. Once you understand them though, they are fantastic for a lot of use cases. Ok, so; on to the code.

# in models.py

graduation_choices = ([(x,str(x)) for x in range(1970,2015)])
graduation_choices.reverse()

class UserProfile(models.Model):
    # usually you want null=True if blank=True. blank allows empty forms in admin, but will 
    # get a database error when trying to save the instance, because null is not allowed
    user = models.OneToOneField(User)       # OneToOneField is more explicit
    network = models.ForeignKey(Network)
    location = models.CharField(max_length=100, blank=True, null=True)
    graduation = models.CharField(max_length=100, blank=True, null=True, choices=graduation_choices)
    headline = models.CharField(max_length=100, blank=True, null=True)
    positions = models.ManyToManyField(Position, blank=True)
    avatar = models.ImageField(upload_to='images/%Y/%m/%d', blank=True, null=True)

    def get_avatar_path(self):
        if self.avatar is None:
            return 'images/default_profile_picture.jpg'
        return self.avatar.name

    def is_complete(self):
        """ Determine if getting started is complete without requiring a field. Change this method appropriately """
        if self.location is None and self.graduation is None and self.headline is None:
            return False
        return True

I stole a piece of this answer for handling the default image location as it was very good advice. Leave the 'which picture to render' up to the template and the model. Also, define a method on the model which can answer the 'completed?' question, rather than defining another field if possible. Makes the process easier.

# forms.py

class UserProfileForm(forms.ModelForm):
    class Meta:
        model = UserProfile
        widgets = {
            'user': forms.HiddenInput() # initial data MUST be used to assign this
        }

A simple ModelForm based on the UserProfile object. This will ensure that all fields of the model are exposed to a form, and everything can be saved atomically. This is how I've mainly deviated from your method. Instead of using several forms, just one will do. I think this is a nicer user experience also, especially since there aren't very many fields at all. You can also reuse this exact form for when a user wants to modify their information.

# in views.py - using class based views available from django 1.3 onward

class SignupMixin(View):
    """ If included within another view, will validate the user has completed 
    the getting started page, and redirects to the profile page if incomplete
    """
    def dispatch(self, request, *args, **kwargs):
        user = request.user
        if user.is_authenticated() and not user.get_profile().is_complete()
            return HttpResponseRedirect('/profile/')
        return super(SignupMixin, self).dispatch(request, *args, **kwargs)

class CheckEmailMixin(View):
    """ If included within another view, will validate the user is active,
    and will redirect to the re-send confirmation email URL if not.

    """
    def dispatch(self, request, *args, **kwargs):
        user = request.user
        if user.is_authenticated() and not user.is_active
            return HttpResponseRedirect('/confirm/')
        return super(CheckEmailMixin, self).dispatch(request, *args, **kwargs)

class UserProfileFormView(FormView, ModelFormMixin):
    """ Responsible for displaying and validating that the form was 
    saved successfully. Notice that it sets the User automatically within the form """

    form_class = UserProfileForm
    template_name = 'registration/profile.html' # whatever your template is...
    success_url = '/home/'

    def get_initial(self):
        return { 'user': self.request.user }

class HomeView(TemplateView, SignupMixin, CheckEmailMixin):
    """ Simply displays a template, but will redirect to /profile/ or /confirm/
    if the user hasn't completed their profile or confirmed their address """
    template_name = 'home/index.html'

These views will probably be the most complicated part, but I feel are much easier to understand than reams of spaghetti view function code. I've documented the functions briefly inline, so it should make it slightly easier to understand. The only thing left is to wire up your URLs to these view classes.

# urls.py

urlpatterns = patterns('',

    url(r'^home/$', HomeView.as_view(), name='home'),
    url(r'^profile/$', UserProfileFormView.as_view(), name='profile'),
    url(r'^confirm/$', HomeView.as_view(template_name='checkemail.html'), name='checkemail'),
)

Now this is all untested code, so it may need tweaks to get working, and to integrate into your particular site. Also, it completely departs from your multi-step process. The multi-step process would be nice in the case of many many many fields.. but a separate page JUST to do the avatar seems a bit extreme to me. Hopefully, whichever way you go, this helps.

Some links regarding class based views:

API Reference
Topic Introduction

I also wanted to mention a few things about your code in general. For instance you have this:

populate_positions = []
for position in positions:
    populate_positions.append(Position.objects.get(label=position))

Which could be replaced with this:

populate_positions = Position.objects.filter(label__in=positions)

The former will hit the DB for every position. The latter will do a single query when evaluated.

Also;

if request.user.is_authenticated():
    username = request.user.username                      
    user = User.objects.get(email=username)

The above is redundant. You've got access to the user object already, and then trying to fetch it again.

user = request.user

Done.

By the way, if you want to use email addresses as a username, you will have problems. The database will only accept a maximum of 30 characters (it is how the User model is writtin in contrib.auth). Read some of them comments on this thread that discuss some of the pitfalls.

Celery task that runs more tasks

6 votes

I am using celerybeat to kick off a primary task that kicks of a number of secondary tasks. I have both tasks written already.

Is there a way to easily do this? Does Celery allow for tasks to be run from within tasks?

My example:

@task
def compute(users=None):
    if users is None:
        users = User.objects.all()

    tasks = []
    for user in users:
        tasks.append(compute_for_user.subtask((user.id,)))

    job = TaskSet(tasks)
    job.apply_async() # raises a IOError: Socket closed

@task
def compute_for_user(user_id):
    #do some stuff

compute gets called from celerybeat, but causes an IOError when it tries to run apply_async. Any ideas?

To answer your opening questions: As of version 2.0, Celery provides an easy way to start tasks from other tasks. What you are calling "secondary tasks" are what it calls "subtasks". See the documentation for Sets of tasks, Subtasks and Callbacks, which @Paperino was kind enough to link to.

Your code shows that you are already familiar with this interface. Your actual question seems to be, "Why am I getting a 'Socket Closed' IOError when I try to run my set of subtasks?" I don't think anyone can answer that, because you have not provided enough information about your program. Your excerpt cannot be run as-is, so we cannot examine the problem you're having for ourselves. Please post the stacktrace provided with the IOError, and with any luck, someone that can help you with your crasher will come along.

Naming dict keys for fast lookup in python

6 votes

I'm going to have 1 small dictionary (between 5 and 20 keys) that will be referenced up to a hundred times or so for one page load in python 2.5.

I'm starting to name the keys which it will be looking up and I was wondering if there is a key naming convention I could follow to help dict lookup times.

I had to test ;-)

using

  • f1, integer key 1
  • f2 short string, "one"
  • f3 long string "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"

as one of the keys into a dictionary of length 4. Iterating 10,000,000 times and measuring the times. I get this result:

<function f1 at 0xb779187c>
f1 3.64
<function f2 at 0xb7791bfc>
f2 3.48
<function f3 at 0xb7791bc4>
f3 3.65

I.e no difference...

My code

Dependency Testing with Python

6 votes

I would like to write unit tests to test whether a dependency exists between two python packages. E.g.:

a/
    __init__.py
    models.py
    views.py
    ...
b/
    __init__.py
    models.py
    views.py
    ...

a unit test to check that modules in package b don't import anything from modules in package a. The only solution I have so far is to scan the files and check that there isn't a "from a" or "import a" in the source code. Are there other ways of doing this? One of the requirements is that a/ and b/ must be in the same directory level.

I would like to have this unit test because I want to be sure that I can use package b in other projects without package a, and also not have other developers write code that will make b dependent on a.

Python is too dynamic to do this 100% correctly. Consider that you can import modules by calling __import__, which takes a string argument so the name of the module to import can be constructed at runtime. Also, __import__ is a function, so it could be bound to other names, so you can't even be sure of detecting all the cases when something is being imported.

And it's technically possible for a module to call a function from another module, which imports a module and returns it. So you definitely can't do this by analysing just package b.

And then there's exec to execute arbitrary python code constructed at runtime...

The closest you could get is probably to try and make your unit test exercise b when a is on the PYTHONPATH, and also when a isn't on the PYTHONPATH. Still not foolproof, as that only tells you that b completed all the tests without a on the PYTHONPATH, not that it doesn't ever need a for anything. And if you're really unlucky, b does something really stupid and fiddles with sys.path in flight and manages to import a anyway somehow.

If, however, this is all your your own code and you know you don't do this kind of wacky crap, then a simple script that scans the files for import statements is probably your best bet. It would probably work very very often on random other people's code too. It's just not possible to do the job perfectly with full generality.

E-commerce from scratch or not

5 votes

I need to develop a new site with the e-commerce part. I'm here to get some hints from you on which road I should go on.

The site will have a static part which include some static pages and the e-commerce part for sell the products. I'm a Django and PHP developer but this is the first time I need to develop an e-commerce.

I see there's some solutions like Satchmo for Django and Magento for PHP. There's also some services like Shopify that provide a pre cooked solution.

These are my requirements:

  • I'll need to give to my site a custom layout/style, all written by me
  • I'll need a nice admin interface for view the incoming orders, the average orders for day and other nice stuff (I see Magento have a very nice panel for this)
  • I'll need a feature that reports me the products that are outgoing out of stock
  • Maybe I'll need to implement a custom payment method
  • Maybe I'll need to implement a custom shipping courier

Of course I prefer Django instead PHP. Anyone can give me an hint? I've never used anyone of this framework/products.

Thank you.

-- EDIT

Deadline is 3 months. Budget ~7500 $. I've three months for finish it.

I've no experience with Django. I develop websites using Wordpress and a year ago I tested Magento (not tested it since).

I was surprised of how user friendly Magento was. Both front end and backend. It was really easy to set up. You can easilly customize the layout as well using Magento template API.

Here are some pros and cons:

Pros

  • Don't develop your own e-commerce site. It's a lot of work to re-invent the wheel.
  • By using a well know e-commers product, you will also find support.
  • E-commerse like Magento is easy to set up and offers the option for change look and feel to match the rest of the web site.
  • You can easilly combine CMS and e-commerce
  • E-commerse apps like Magento offers the option for custom static / dynamic pages (like a mini cms)
  • You will save money (development time) by using something that is already developed
  • Most e-commerce sites handles payment towards different banking providers.

Cons

  • Magento does not work on all servers (server configuration). This however might have changed the past year.
  • If free e-commers products like Magento does not sattisfy your needs, you need to buy licenses. And that costs a lot of money.
  • It takes a lot of time developing your own e-commerce site if you want quality and usability. There is no way you can develop a good e-commerce site from scratch in just 3 months.

Is get_or_create() thread safe

5 votes

I have a Django model that can only be accessed using get_or_create(session=session), where session is a foreign key to another Django model.

Since I am only accessing through get_or_create(), I would imagine that I would only ever have one instance with a key to the session. However, I have found multiple instances with keys to the same session. What is happening? Is this a race condition, or does get_or_create() operate atomically?

Actualy it's not thread-safe, you can look at the code of the get_or_create method of the QuerySet object, basicaly what it does is the following :

try:
    return self.get(**lookup), False
except self.model.DoesNotExist:
    params = dict([(k, v) for k, v in kwargs.items() if '__' not in k])
    params.update(defaults)
    obj = self.model(**params)
    sid = transaction.savepoint(using=self.db)
    obj.save(force_insert=True, using=self.db)
    transaction.savepoint_commit(sid, using=self.db)
    return obj, True

So two threads might figure-out that the instance does not exists in the DB and start creating a new one, before saving them consecutively.

Django dev server slowness with chrome + other instance / browser

5 votes

First let me say that this is not about production settings for django - it's for local development and testing.

I'm testing out multiple user scenarios, requiring I log in as several different users. I'm logged in as user A using Chrome, and user B using Chrome's incognito mode, and as user C using Firefox. I'm using "manage.py runserver" to run the dev server.

The first instance with regular Chrome (user A) works well and is fast. The other instances are very slow - perhaps better described as stuck. They sit around doing nothing for 10-30 seconds, and then finally display the page fairly quickly.

While the other browsers are stuck I can go to the first one (user A) and click around and it works well and is fast. In other words only the requests from the other two instances get stuck - the first instance always works well.

The resource that's slow appears to be the html page, not the static content.

The backend is Django 1.1.1 with SQLite as the database running on OS X 1.6.7 .

Any ideas? Is Chrome doing something special to hog the connection?

This could be a known issue "Development web server sometimes hangs with Chrome":

https://code.djangoproject.com/ticket/16099

It is fixed recenty in django trunk:

https://code.djangoproject.com/changeset/16427

Problem with class based generic views in Django

5 votes

I'm trying to write a CRUD application using Djangos class based generic views. Following is the code i wrote to create a new user in the db.

  from django.views.generic import CreateView
  from django.contrib.auth.decorators import login_required
  from django.contrib import messages

  class UserCreateView(CreateView):
  """ 
  Display and accept a new user to be created in db
  """
    form_class = ProfileForm
    template_name = 'userdb/profile_form.html'
    success_url = '/organization/users/'

    def post(self, request, *args, **kwargs):
      messages.success(request, "Success", extra_tags='msg')
      return super(UserCreateView, self).post(request, *args, **kwargs)

    @method_decorator(login_required)
    def dispatch(self, *args, **kwargs):
      return super(UserCreateView, self).dispatch(*args, **kwargs)

Note that to add a success message to be displayed to the user I've had to extend the post function. I know this is not a good way to do this as, when this function gets called it's not decided whether the submitted form contains valid data. So my question is, Is there recommended way of combining Djangos messaging framework with class based generic views?

The answer depends on what specifically you're looking to do with the messaging framework. If it needs to be called for every get request you'd naturally need to put it in the get method (point being there's no one right place to put this code).

Anyways, it sounds like you're looking for a place that's only triggered when the form is valid.

CreateView uses the ModelFormMixin which implements a form_valid method which is only fired upon successful form saving. Perfect!

def form_valid(self, form):
    messages.success(self.request, "Success", extra_tags='msg')
    return super(UserCreateView, self).form_valid(form)  
    # ModelFormMixin will now save
    # FormMixin will now redirect to success_url()
    # override above behavior if you need to do something with the object

get the version of django for application

5 votes

I am starting a new( actually very old) project which I know is in django. I am getting lost knowing the exact version of django it has been build upon. Is there any way I can know the version of Django my app is running ?

The only way is to take a guess. I would start by looking at the created date of the settings.py file (or other base project files)

release dates for versions:

  • 1.0: September 2008. (?)
  • 1.1: July 29, 2009 [1]
  • 1.2: May 17, 2010 [2]
  • 1.3: March 23, 2011 [3]

having in your urls.py:[4]

from django.conf.urls.defaults import *
from django.contrib import admin

or having an admin.py file in an app [5]

suggests that it is a 1.0+ project.

having in your urls.py: [6]

(r'^admin/', include(admin.site.urls)),

would suggest 1.1+

having in your settings.py file:

DATABASES = {
    'default': {
        'NAME': 'app_data',
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'USER': 'postgres_user',
        'PASSWORD': 's3krit'
    },
    'users': {
        'NAME': 'user_data',
        'ENGINE': 'django.db.backends.mysql',
        'USER': 'mysql_user',
        'PASSWORD': 'priv4te'
    }
}

would suggest 1.2+.

[1]: 1.1 release notes

[2]: 1.2 release notes

[3]: 1.3 release notes

[4]: backwards Incompatible changes 0.96 > 1.0

[5]: backwards Incompatible changes 0.96 > 1.0

[6]: multiple databases