Подтвердить что ты не робот

Выберите элемент в Django admin inline с помощью переключателей

Вот часть моих models.py:

class Person(models.Model):
    birth_year = WideYear(null=True, blank=True)
    birth_year_uncertain = models.BooleanField()
    death_year = WideYear(null=True, blank=True)
    death_year_uncertain = models.BooleanField()
    flourit_year = WideYear(null=True, blank=True)
    flourit_year_uncertain = models.BooleanField()
    FLOURIT_CHOICES = (
        (u'D', u'Birth and death dates'),
        (u'F', u'Flourit date'),
    )
    use_flourit = models.CharField('Date(s) to use', max_length=2, choices=FLOURIT_CHOICES)
    def __unicode__(self):
        if self.personname_set.filter(default_name__exact=True):
            name = z(self.personname_set.filter(default_name__exact=True)[0])
        else:
            name = u'[Unnamed person]'
        if self.use_flourit == u'D':
            dates = '%s - %s' % (z(self.birth_year), z(self.death_year))
        else:
            dates = 'fl. %s' % (z(self.flourit_year))
        return '%s (%s)' % (name, dates)
    class Meta:
        ordering = ['ordering_string']

class PersonName(models.Model):
    titles = models.CharField(max_length=65535, null=True, blank=True)
    surname = models.CharField(max_length=255, null=True, blank=True)
    first_name = models.CharField(max_length=255, null=True, blank=True)
    middle_names = models.CharField(max_length=255, null=True, blank=True)
    post_nominals = models.CharField(max_length=65535, null=True, blank=True)
    default_name = models.BooleanField()
    person = models.ForeignKey(Person, null=True, blank=True)
    def __unicode__(self):
        return '%s, %s %s' % (self.surname, self.first_name, self.middle_names)
    class Meta:
        unique_together = ("titles", "surname", "first_name", "middle_names", "post_nominals", "person")
        unique_together = ("default_name", "person")
post_save.connect(post_save_person_and_person_name, sender=PersonName)

Я хочу, чтобы имя_объекта редактировалось в строке с личностью в админе как TabularInline. Кроме того, я хочу, чтобы поле default_name PersonName отображалось как переключатель, так что только одно имя PersonName для человека может иметь default_name = True.

Это та последняя часть, что жесткий бит. В Django относительно легкий интерфейс в форме. Наличие того, которое выбирает, по существу, одну форму в наборе форм, оказывается намного сложнее.

Один из способов сделать это - добавить JavaScript в change_form.html для Person, который использует регулярное выражение для соответствия <input> элементов для default_name и гарантирует, что проверка одного из них отменяет остальное. Но похоже, что это может сломаться, если соглашение Django для обозначения полей формы HTML изменится; плюс, это только исправило бы вопросы для пользователей с браузерами с поддержкой JavaScript.

Любые лучшие идеи с благодарностью получили!

ОБНОВЛЕНИЕ 17/9/2009

Следующее расширение шаблона администратора (на основе this и this) реализует предложение JavaScript выше, но лучшие решения будут приветствоваться!

{% extends "admin/change_form.html" %}

{% block extrahead %}
    <script src="/site_media/jquery-1.3.2.min.js" type="text/javascript"></script>
    <script type="text/javascript">
        jQuery(document).ready(function(){
            // Replace default_name checkboxes with radio buttons.
            $(".default_name input").each(function(){
                var name = $(this).attr('name'); // grab name of original
                var id = $(this).attr('id'); // grab id of original
                if ($(this).attr('checked')) { // grab checked value of original
                    var checked = ' checked="checked"';
                } else {
                    var checked = '';
                }
                /* create new visible input */
                var html = '<input type="radio" name="'+name+'" id="'+id+'" value="True"'+checked+' />';
                $(this).after(html).remove(); // add new, then remove original input
            });
            // Ensure only one default_name radio button can be checked at a time.
            $(".default_name input").click(function(){
                $(".default_name input").not(this).removeAttr("checked");
            });
        });
    </script>
{% endblock %}
4b9b3361

Ответ 1

Я думаю, вы не получите обычный метод только для HTML, чтобы делать то, что вы хотите.

Однако вам не придется полагаться на регулярное выражение. Невозможно добавить имя класса в поля ввода, чтобы jquery...

Я думаю, что это было труднее, чем я думал (ответил здесь): Определить класс css в форматах django

Это лишь немного лучшее решение.