Opened 13 years ago

Closed 10 years ago

#17214 closed Bug (fixed)

incorrect rendering of inline fk when parent has custom pk field

Reported by: Aryeh Leib Taurog <vim@…> Owned by: nobody
Component: Forms Version: 1.3
Severity: Normal Keywords:
Cc: vim@… Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

pkfk/models.py

from django.db import models

class TZDateField(models.DateField):
    description = "Date field stored in PostgreSQL as TIMESTAMP WITH TIME ZONE"
    __metaclass__ = models.SubfieldBase
    def db_type(self, connection): return "TIMESTAMP WITH TIME ZONE"

class FooDate(models.Model):
    foo_date = TZDateField(primary_key=True)

class Bar(models.Model):
    baz  = models.CharField(max_length=10)
    foo_date = models.ForeignKey("FooDate")
    class Meta:
        unique_together = ("baz", "foo_date")

pkfk/admin.py

from django.contrib import admin
from pkfk.models import FooDate, Bar

class BarInline(admin.TabularInline):
    model = Bar

class FooDateAdmin(admin.ModelAdmin):
    inlines = [BarInline]

admin.site.register(FooDate, FooDateAdmin)

When trying to re-save inline objects in the admin, I get a mysterious "Please correct the errors below." message, but no further error messages are displayed. If I supply my own inline formset and catch the clean() call, I can see the following formset.errors:

[{'foo_date': [u'The inline foreign key did not match the parent instance primary key.']},
 {'foo_date': [u'The inline foreign key did not match the parent instance primary key.']},
 {},
 {},
 {}]

This is because html for the hidden foreign key field on the inline is rendered as follows:

<input type="hidden" name="bar_set-0-foo_date" value="2011-11-12 00:00:00" id="id_bar_set-0-foo_date">

In order for this to work it needs to be rendered without the time:

<input type="hidden" name="bar_set-0-foo_date" value="2011-11-12" id="id_bar_set-0-foo_date">

If the inline form would only call the pk field's to_python or get_prep_value before rendering the fk, it would be correct, but it seems to be pulling it straight from the db and rendering that datum on its own. Perhaps this ticket is related? Am I missing something?

I tried this and got the same results under 1.2.4, 1.2.7, and 1.3.1.

Change History (5)

comment:1 by Aymeric Augustin, 13 years ago

Resolution: duplicate
Status: newclosed

I'm pretty sure this is a duplicate of #17122. This ticket has patches, could you test if they resolve your problem?

in reply to:  1 comment:2 by Aryeh Leib Taurog <vim@…>, 13 years ago

Resolution: duplicate
Status: closedreopened

Replying to aaugustin:

I'm pretty sure this is a duplicate of #17122. This ticket has patches, could you test if they resolve your problem?

Yes, I also thought so. I should have mentioned that I tried that patch before submitting this bug. It does not solve the problem. Feel free to give it a whirl. All you need to test are the models.py and admin.py I posted and a postgresql db.

comment:3 by Aymeric Augustin, 13 years ago

Triage Stage: UnreviewedAccepted

Since your report contains enough detail to reproduce the problem, and the bug looks plausible, I'm accepting the ticket (I didn't attempt to reproduce it myself).

comment:4 by Aymeric Augustin, 12 years ago

Status: reopenednew

comment:5 by Claude Paroz, 10 years ago

Resolution: fixed
Status: newclosed

I think that the addition of from_db_value() in Django 1.8 solves this issue.
https://docs.djangoproject.com/en/1.8/ref/models/fields/#django.db.models.Field.from_db_value

Here's what would be a functional TZDateField definition:

class TZDateField(models.DateField):
    description = "Date field stored in PostgreSQL as TIMESTAMP WITH TIME ZONE"

    def db_type(self, connection):
        return "TIMESTAMP WITH TIME ZONE"

    def from_db_value(self, value, expression, connection, context):
        if value is not None:
            return self.to_python(value)
        return value
Note: See TracTickets for help on using tickets.
Back to Top