在单选按钮中内联选择Django admin中的项目 [英] Select item in Django admin inline with radio buttons

查看:107
本文介绍了在单选按钮中内联选择Django admin中的项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的模型的一部分。

Here's part of my 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)

我希望PersonName可在admin作为TabularInline。另外,我希望PersonName的default_name字段显示为单选按钮,这样每个人只有一个PersonName可以具有default_name = True。

I want PersonName to be editable inline with Person in the admin as a TabularInline. Also, I want the default_name field of PersonName to display as a radio button, such that only one PersonName per Person can have default_name=True.

这是最后一部分很难。在Django中,在表单中具有单选按钮界面相对容易。从本质上说,让一个表单选择表单集中的一种表单似乎要困难得多。

It's that last part that's the hard bit. Having a radio button interface within a form is relatively easy in Django. Having one that selects, essentially, one form in a formset, appears to be much, much harder.

做到这一点的一种方法是将JavaScript添加到change_form中。使用正则表达式匹配< input>的Person的html。 default_name元素,并确保选中其中之一会取消选中其余元素。但是,如果Django的HTML表单字段命名约定发生更改,这似乎就可能被打破;另外,它只会解决启用JavaScript的浏览器用户的问题。

One way to do this would be to add JavaScript to the change_form.html for Person that uses a regex to match the <input> elements for default_name and ensures that checking one of them unchecks the rest. But this seems as though it might become broken if Django's convention for naming HTML form fields changes; plus, it would only fix matters for users with JavaScript-enabled browsers.

任何更好的想法都会得到感激!

Any better ideas gratefully received!

UPDATE 17/9/2009

以下管理模板扩展名(基于)实现了上述JavaScript建议,但欢迎使用更好的解决方案!

The following admin template extension (based on this and this) implements the JavaScript suggestion above, but better solutions would be welcomed!

{% 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 %}


推荐答案

我认为

您不必在这里依靠正则表达式。您不能在输入字段中添加类名称,以使jquery ...

You shouldn't have to rely on regex here though. Can't you add a class name to your input fields so that jquery...

我想这比我最初想的要难(在这里回答):
在Django表单中定义css类

I guess that's harder than I first thought (answered here): Define css class in django Forms

不过这只是一个更好的解决方案。

It's only a slightly better solution though.

这篇关于在单选按钮中内联选择Django admin中的项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆