Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django表单,包含来自数据库的链接(URL)选项,并能够输入新URL(自由文本)_Python_Django_Django Forms - Fatal编程技术网

Python Django表单,包含来自数据库的链接(URL)选项,并能够输入新URL(自由文本)

Python Django表单,包含来自数据库的链接(URL)选项,并能够输入新URL(自由文本),python,django,django-forms,Python,Django,Django Forms,我希望能够有一个下拉列表的选择,从数据库中的链接(网址),也有一个文本输入框来创建一个新的网址 我已经看到了问题的答案 这个问题的作者给出的答案似乎最接近我的需要,但我有一些不同之处: 这些选项来自数据库 这些选项应该能够链接到URL 这对Django可行吗 我想有一个链接只有下拉。文本框将显示所选链接——此链接也将位于下拉列表中。如果在文本框中输入新链接,该链接将添加到数据库和下拉列表中 我还想从下拉列表中删除条目——这将从数据库中删除它们。可能在下拉列表中的每个链接旁边都有一个“x”,以便在

我希望能够有一个下拉列表的选择,从数据库中的链接(网址),也有一个文本输入框来创建一个新的网址

我已经看到了问题的答案

这个问题的作者给出的答案似乎最接近我的需要,但我有一些不同之处:

  • 这些选项来自数据库
  • 这些选项应该能够链接到URL
  • 这对Django可行吗

    我想有一个链接只有下拉。文本框将显示所选链接——此链接也将位于下拉列表中。如果在文本框中输入新链接,该链接将添加到数据库和下拉列表中

    我还想从下拉列表中删除条目——这将从数据库中删除它们。可能在下拉列表中的每个链接旁边都有一个“x”,以便在单击时将其从数据库和下拉列表中删除。如果最后一部分过于繁琐,可以采用另一种方式

    这是我目前掌握的代码。下拉框中显示的是“----------”,文本框中显示的是“0x7f869910af10处的fields.UrlChoiceField对象”:

    forms.py:

    class Form(ModelForm):
      detail_urls = common_fields.UrlChoiceField(
          label='Detail URLs', required=False,
          queryset=common_models.DetailUrl.objects.none(),
          help_text='List of Detail URLs from which to pick.  Can be null.')
    
      def __init__(self, *args, **kwargs):
        super(Form, self).__init__(*args, **kwargs)
        if self.instance.pk:
          if 'detail_urls' in self.fields:
            queryset = self.instance.detail_urls.all()
            self.initial.update({
                'detail_urls': common_fields.UrlChoiceField(queryset=queryset)})
    
    fields.py:

    class OptionalChoiceWidget(forms.MultiWidget):
      def __init__(self, *args, **kwargs):
        queryset = kwargs.pop('queryset')
        widgets = (
            forms.Select(choices=queryset),
            forms.TextInput())
        super(OptionalChoiceWidget, self).__init__(*args, **kwargs)
    
      def decompress(self, value):
        if value:
          if value in [x[0] for x in self.widgets[0].choices]:
            return [value, '']
          return ['', value]
        return ['', '']
    
    class UrlChoiceField(forms.MultiValueField):
      def __init__(self, queryset, *args, **kwargs):
        fields = (
            forms.ModelChoiceField(queryset=queryset, required=False),
            forms.CharField(required=False))
        self.widget = OptionalChoiceWidget(
            queryset=queryset, widgets=[f.widget for f in fields])
        super(UrlChoiceField, self).__init__(fields, *args, **kwargs)
    
      def compress(self, data_list):
        if not data_list:
          raise exceptions.ValidationError(
              'Need to select choice or enter text for this field')
        return data_list[0] or data_list[1]
    
    class URLWidget(forms.TextInput):
      """Widget for displaying an URLField input with clickable link."""
    
      def render(self, name, value, attrs=None):
        """Defines HTML representation for this widget."""
        cls = ''
        attrs = attrs or {}
        if 'class' in attrs:
          cls = ' ' + attrs['class']
        attrs['class'] = 'autolink' + cls
        html = super(URLWidget, self).render(name, value, attrs)
        return safestring.mark_safe(html)
    
    class URLField(models.CharField):
      """A CharField with milder validation of URLs than Django's URLField."""
    
      default_validators = [validators.ValidateUrl]
    
      def __init__(self, *args, **kwargs):
        if 'max_length' not in kwargs:
          kwargs['max_length'] = 512
        super(URLField, self).__init__(*args, **kwargs)
    
      def formfield(self, **kwargs):
        kwargs['widget'] = URLWidget
        return super(URLField, self).formfield(**kwargs)
    
    class DetailUrlField(URLField):
      """A URLField that becomes auto-linked in list view."""
    
      def ListDisplay(self, value=None, unused_instance=None):
        if not value:
          value = ''
        else:
          value = html_utils.escape(value)
          value = filters.AutoLink(value)
        return value
      ListDisplay.allow_tags = True
    
    models.py:

    class MyModel(Model):
      detail_urls = ct_fields.GenericRelation(
          'common.DetailUrl', object_id_field='object_pk')
    
    class DetailUrl(models.Model):
      content_type = models.ForeignKey(ct_models.ContentType)
      object_pk = models.PositiveIntegerField(db_index=True)
      content_object = ct_fields.GenericForeignKey(fk_field='object_pk')
      detail_url = common_fields.DetailUrlField(
          'Detail URL', blank=True, help_text='URL to relevant information.',
          max_length=255)
    
      class Meta(object):
        ordering = ('detail_url',)
        unique_together = ('content_type', 'object_pk', 'detail_url')
    
      def __unicode__(self):
        return u'%s: %s' % (self.content_object, self.detail_url)
    
      def ListDisplay(self, unused_value=None, unused_instance=None):
        """Provides formatting of detail_url in list view."""
        content = self.detail_url
        content = filters.AutoLink(content)
        return content
      ListDisplay.allow_tags = True
    
      def ExportDisplay(self):
        return self.detail_url
    

    是的,它是可以做到的。您可以在表单中使用ModelChoiceField并指定“queryset”将值从数据库拉到下拉列表中,但我无法在表单下拉列表中显示可单击的链接。下拉菜单是一个带有选项的菜单,其中选项有一个值(通常是主键)和文本(不是链接)。你的下拉列表是什么样子的?你有这样的例子吗?或者你想用文本字段显示UL内部的链接以输入新值吗?我添加了一些文本和代码片段来回答你的问题。非常感谢。