tags:

views:

95

answers:

2

I have a model Category which has a ForeignKey to a SimplePage model. null and blank are set to True. The problem is, when I edit a Category from the admin interface, I can't change the ForeignKey to --------- (Which looks like the admin's way of saying None.) The value can be None initially, and I can change it to an actual value through the admin, and I can change to another value, but once it has an actual value I can't change it back to None. (Through the admin, that is.)

Why is this?

UPDATE:

Here's the code for models.py:

from django.db import models
import tinymce.models
from photologue.models import Photo

from django.utils.translation import ugettext_lazy as _
import multilingual

class SimplePage(models.Model):

    slug = models.SlugField(
        _('Slug'),
        unique=True,
        help_text=_('''Unique identifier for URL. Only letters, digits, and -.\
e.g. history-oct-2000 or about''')
    )

    category = models.ForeignKey('Category',
                                 related_name='items_including_main_page',
                                 blank=True, null=True)

    class Translation(multilingual.Translation):
        title = models.CharField(_('Title'), max_length=42)
        content = tinymce.models.HTMLField(_('Content'), blank=True)

    class Admin:
        list_display = ('title',)
        search_fields = ('title', 'content')

    class Meta:
        verbose_name = _('Simple page')
        verbose_name_plural = _('Simple pages')

    __unicode__ = lambda self: self.title


class Category(models.Model):
    main_page = models.OneToOneField(
        SimplePage,
        related_name='_SimplePage__category_which_has_this_as_title', 
        blank=True,
        null=True)

    get_title = lambda self: self.main_page.title if self.main_page else u''

    get_items = lambda self: \
        self.items_including_main_page.exclude(id__exact=self.main_page.id)

    __unicode__ = lambda self: self.get_title() or u'Titleless Category'

    class Admin:
        pass

    class Meta:
        verbose_name = _('Category')
        verbose_name_plural = _('Categories')

And admin.py:

from sitehelpers.models import *
from django.contrib import admin
import multilingual

class SimplePageAdmin(multilingual.ModelAdmin):
    pass

admin.site.register(SimplePage, SimplePageAdmin)

admin.site.register(Category)
+2  A: 

Maybe that's because you have OneToOne relationship defined also in category and you can't therefore break this relationship. Try to remove it and see, if you can set category in SimplePage to None.

gruszczy
I think I miscommunicated in my original question: The relation that I can't change to `None` is the OneToOneField in Category, not the other one.Also, I now confirmed that I *can* change it through `manage.py shell`, but still not through the admin.
cool-RR
As in the below answer, you can't change OneToOne relation to None. So, either way, you can't change the value to None from any model in admin. Maybe admin performs validation for that and that's why it doesn't allow you to change that. Anyway, having ForeignKey on one side and OneToOne on the other isn't a good way to go.
gruszczy
Can you propose a different architecture? Every Category has a SimplePage which is its main page, and also a bunch of SimplePages which are items. How would you do it?
cool-RR
Hmm.. How about Category having ForeignKey to the main page and ManyToMany to other pages? You will also need to write some validation in save, but I believe this should work.
gruszczy
When I write validation in save, will it also validate when saving through the admin? (And give a user-friendly error message?)
cool-RR
It will validate everywhere, where you call save. I can't be absolutely sure, whether admin forms call Model.save, but I am pretty certain they do. Take a look at the source code (or run a simple test ;-)). I don't know, what do you mean user friendly error message. If you mean messages in the form, then no - these are provided by raising ValidationError in clean methods.
gruszczy
That would be a problem then-- I need something that will be easy to edit for a non-technical user on Django's admin.
cool-RR
Figured out a better architecture: No `Category` model. Every SimplePage will point to its parent.
cool-RR
This is nice. Tree based architecture. Clever :-)
gruszczy
A: 

gruszczy above is right, each side of o2o relation cannot be null after it was assigned, because django won't let you have orphan object in DB.

Dmitry Shevchenko