Opened 2 years ago

Closed 2 years ago

#20228 closed Bug (fixed)

Admin interface doesn't prevent duplicates with unique_for_date

Reported by: monuszko Owned by: iapain
Component: Documentation Version: 1.4
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I'm using Python 2.7.3 and Django 1.4.5-1 from Debian repositories. I can add multiple entries with identical values and the admin interface doesn't complain. I tried with both 'slug' and 'title'.
It sounds just like the bug from 4 years ago: https://code.djangoproject.com/ticket/10134

Note that while my field is DateTimeField (with time), the wording of the description at
https://docs.djangoproject.com/en/dev/ref/models/fields/#unique-for-date leads me to believe it should consider only the .date component of the DateTimeField.

# models.py

from django.db import models

from django.utils.timezone import now as utcnow
now = utcnow() # replacing - date.now() causes problems with auto_now_add

class Entry(models.Model):
    created_at = models.DateTimeField(default=now, editable=False)
    title      = models.CharField(max_length = 50)
    content    = models.TextField()
    slug       = models.SlugField(unique_for_date='created_at')

    def __unicode__(self):
        return self.title
    class Meta:
        ordering = ['-created_at']

# admin.py

from news.models import Entry
from django.contrib import admin

class EntryAdmin(admin.ModelAdmin):
    prepopulated_fields = {'slug': ('title',)}

    list_filter = ['created_at']
    date_hierarchy = 'created_at'

admin.site.register(Entry, EntryAdmin)

Change History (9)

comment:1 Changed 2 years ago by aaugustin

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Accepted

I guess it currently does unique_for_datetime when used on a DateTimeField.

Changing to operate only on the date part is backwards incompatible, but I've already made a bunch of similar cleanups, I suppose we can do one more.

comment:2 Changed 2 years ago by monuszko

Either way, functionality should match the documentation. To my understanding of English, it currently doesn't. An extra sentence for clarification of DateTimeField would be nice. I can't evaluate how important backwards compatibility is in this case, but from programmer convenience point of view it would be very nice to have unique_for_date only consider the .date component. "unique_for_datetime" can already be achieved with unique_together.

comment:3 Changed 2 years ago by svisser

This seems similar to #18427; fixing one may also provide a stepping stone to fixing the other.

comment:4 Changed 2 years ago by iapain

  • Component changed from Uncategorized to contrib.admin

It looks like valid bug. Fortunately, it's limited to contrib.admin. I was unable to repeat this in ModelForms, Forms and Model Validation.

comment:5 Changed 2 years ago by iapain

  • Owner changed from nobody to iapain
  • Status changed from new to assigned

comment:6 Changed 2 years ago by iapain

The reason for this is validate_unique skips "created_at" because it's internally in excluded fields since it's not rendered in admin UI.

@aaugustin Shouldn't we check f.name instead of f.unique_for_* in exclude? https://github.com/django/django/blob/master/django/db/models/base.py#L800-L804 ? If not then we should mark it as documentation bug and add a note in documentation that field should not be excluded.

Last edited 2 years ago by iapain (previous) (diff)

comment:7 Changed 2 years ago by iapain

  • Component changed from contrib.admin to Database layer (models, ORM)

comment:8 Changed 2 years ago by iapain

  • Component changed from Database layer (models, ORM) to Documentation
  • Has patch set

comment:9 Changed 2 years ago by Tim Graham <timograham@…>

  • Resolution set to fixed
  • Status changed from assigned to closed

In d321d1acf0fdf00247e78b9686be84c18b35b9d8:

Fixed #20228 - Documented unique_for_date and exclude behavior.

Thanks Deepak Thukral for the patch.

Note: See TracTickets for help on using tickets.
Back to Top