我有一个模型Label
用于保留我网站中出现的字符串:
class Label(models.Model):
key = models.CharField(max_length=32, primary_key=True)
value = models.CharField(max_length=128,blank=True, default='')
我想创建一个表单来自定义这些字符串。看起来像这样:
Site Configuration
this_is_key: this_is_value_____________
site_title: ________________
site_subtitle: _________________
site_copyright_info: _________________
admin_email: _________________
admin_phone: _________________
[Save]
当任何键的值不存在时,Label.create()
具有我们预先定义的默认值。
现在,如何使用forms.Form
或forms.ModelForm
(或其他任何东西......我不确定是否使用类似formset
之类的东西来完成此任务)来完成此操作工作?我一直在寻求解决方案好几天。
答案 0 :(得分:2)
我的小解决方案。 https://kuanyui.github.io/2015/08/10/django-key-value-pairs-model-and-form/
settings.py
在settings.py
中定义标签:
LABELS = [
# ('key', 'label in form', 'default value'),
('site_title' , 'Site Title', 'Hello World!'),
('copyright_info' , 'Copyright Info', 'John Smith (c) 2015'),
('admin_email' , 'Your E-mail', '02 1234 5678'),
]
from django.conf import settings
from django.db import models
class Label(models.Model):
key = models.CharField(max_length=32, primary_key=True)
value = models.CharField(max_length=128,blank=True, default='')
@classmethod
def get_label(cls, key):
"""Get the value of a label via key.
If not found, create one with the default value in
settings.LABELS."""
try:
return cls.objects.get(key=key).value
except:
default_value = [x for x in settings.LABELS if x[0] == key][0]
cls.objects.create(key=key, value=default_value)
return default_value
我们定义save()
方法将request.POST
保存到我们的模型中。
from django import forms
from pages.models import Label
from django.conf import settings
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit, Layout, Div, Button, Fieldset, HTML
class LabelForm(forms.Form):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for key, label, default_value in settings.LABELS: # settings.LABELS
self.fields[key] = forms.CharField(max_length=128)
self.fields[key].label = label
# get_or_create => (<Label: Label object>, False)
labelObj, _ = Label.objects.get_or_create(
key=key,
defaults={'value': default_value})
self.fields[key].initial = labelObj.value
self.helper = FormHelper()
self.helper.add_input(Submit('submit', 'Submit'))
def save(self, POST):
for key, _, _ in settings.LABELS:
Label.objects.filter(key=key).update(value=POST[key])
from pages.models import Label
from pages.forms import LabelForm
class LabelSettings(FormView):
template_name = "label_settings.html"
form_class = LabelForm
success_url = '.' # whatever.
def form_valid(self, form):
super().form_valid(form)
form.save(self.request.POST) # pass POST dict to LabelForm.save()
return HttpResponseRedirect(self.get_success_url())
label_settings.html
此页面用于编辑/保存我们的标签。
<form method="post" action="">
{% crispy form %}
</form>
from django import template
from pages.models import Label
register = template.Library()
@register.simple_tag
def label(key):
return Label.get_label(key)
{% load common_tags %}
<h1>{% label 'site_title' %}</h1>
答案 1 :(得分:1)
如果没有编写完整的新库,您似乎无法使用forms.Forms。你要求在运行时创建一个表单模型,这在我看来很难做到。
如果这是您想要采用的方法,我的建议是编写您自己的自定义表单类。但是,请注意,您想要包含的任何验证或其他功能都必须与每个Label一起存储在数据库中。因此,如果您希望给定标签最多包含150个字符,则必须将其与键和值一起存储,以便您可以在运行时执行自己的验证