views:

212

answers:

3

I'm using Django (specifically django-admin) to be the admin panel for a site that uses PHP for client-facing features. I've been messing around making the admin look exactly the way I want and so far so good. However, I've run into a few problems that I need solving.

Here's the models that I'm working with:

class Permissions(models.Model):
    id = models.IntegerField(primary_key=True)
    league_key = models.CharField(max_length=15) 
    commissioner_id = models.ForeignKey(Accounts, db_column='commissioner_id',
                                        to_field='id')
    status = models.IntegerField()
    key = models.CharField(max_length=50)
    publisher_key = models.CharField(max_length=25)
    publisher_display_name = models.CharField(max_length=50)
    base_league = models.ForeignKey('self', db_column='id')
    share = models.IntegerField()
    default_fixture_key = models.CharField(max_length=50)

    def __unicode__(self):
        return self.publisher_key + ' / ' + self.league_key

    class Meta:
        db_table = u'permissions'
        verbose_name = 'Permissions'
        verbose_name_plural = 'Permissions'

class PermissionsAdmin(admin.ModelAdmin):
    list_display = ('league_key', 'publisher_key', 'commissioner_id', 'status',
                    'base_league', 'share', 'default_fixture_key')
    list_display_links = ('league_key','commissioner_id', 'base_league')
    exclude = ('id',)

First problem is that the admin form for editing an existing record is marking one of the fields as required. How do I tell the django-admin when a field is required and not required?

Second problem I am running into is that when I tell it to Save this record, I get the following error: duplicate key value violates unique constraint "permissions_pkey". That leads me to think that Django is not doing an update, it's trying to do an INSERT

It also occurred to me that this might be a problem related to Postgresql. permissions_pkey is a constraint on that table, keeping track of the sequence being used for auto-incrementing the id for that table

While the Django docs are awesome, they don't seem to have the info I need to figure this out.

(EDIT: Digging into the stack trace, I found this awesome little nugget:

sql 
'UPDATE "permissions" SET "league_key" = E\'l.1258472565 \', "commissioner_id" = 7,
 "status" = 0, "key" = E\'cfcd208495d565ef66e7dff9f98764da \', 
"publisher_key" =     E\'chrishartjes.com \', 
"publisher_display_name" = E\'Chris Hartjes Free Press \', 
"id" = 744, "share" = 0, 
"default_fixture_key" = E\'\' WHERE "permissions"."id" = 745 '

which leads me to think that my little ForeignKey to itself entry is causing the problem)

+1  A: 
  1. On the field, put null=True in the field constructor if the field is not required. Edit: commenter says blank=True -- he's probably right -- I don't have the docs in front of me.
  2. It does an insert if the ID is empty and an update if the id has a value. Not sure where the save you are talking about is happening, but that info might help. (there's a deleted answer that points out that the exclude('id') is probably causing this problem -- I think that's right as well)

Also, I agree about the docs. If you can read python, I highly suggest just trying to read the Django source code for the area you want to figure out. The source is some of the nicest, most readable source I've ever read. I've never had a problem just jumping in and reading it -- it's almost as good as a doc.

Lou Franco
`blank=True` will make a field not required. `null=True` only affects null values being permissible for blank fields in the database; it does not affect validation
Ben James
+2  A: 

Problem 1: See the documentation on setting null and blank. Short story: setting null will allow the DB to store a null value. What you want here (most likely) is to set blank to True so that when it validates the model that field won't be required. If the field isn't a CharField, you should also set null to True. See the docs here: http://docs.djangoproject.com/en/dev/ref/models/fields/#field-options

Problem 2: I believe that what you want here is an AutoField, not an IntegerField. The difference is just that an AutoField will create a new id for you automatically when saving a new object. See the docs here: http://docs.djangoproject.com/en/dev/ref/models/fields/#autofield

Edit: (from my comment) Looking again I see that the error references permissions_pkey. Try replacing the id field with pkey = AutoField(primary_key=True).

John Debs
Added in blank=True for the field in question and it works just fine now. Changing to AutoField appears to have done nothing to fix the problem of the pkey error being reported, and I have removed the exclude('id',) line as well. :(
GrumpyCanuck
You'll need to drop and recreate your table after changing to AutoField. In fact I'd recommend leaving out the `id` field altogether - Django automatically adds it if you do.
Daniel Roseman
I can't drop and recreate the table as it's full of working data
GrumpyCanuck
Since you mention existing data it may be worthwhile to look at managed models (http://docs.djangoproject.com/en/dev/ref/models/options/#managed) although I don't think your issue is related.
John Debs
Looking again I see that the error references `permissions_pkey`. Try replacing the `id` field with `pkey = AutoField(primary_key=True)`.
John Debs
A: 
  1. null=True, blank=True

  2. You don't need to explicitly have the "id" column in your Permissions model, I believe that's what's causing your second problem.