假设我有一个Pen的数据模型。钢笔可以是金属的,也可以是木头的。金属笔可以是银色或白色的木制钢笔可以是蓝色的或绿色的。所以不能有蓝色的金属笔
是否有办法取代添加按钮中的材料选择,以显示材料名称/颜色的组合?我认为字段集一定有问题。
# model.py
from django.db import models
class Color(models.Model):
color = models.CharField(max_length=20, primary_key=True)
def __unicode__(self):
return self.color
class Material(models.Model):
type = models.CharField(max_length=20)
color = models.OneToOneField(Color)
def __unicode__(self):
return "%s_%s" % (str(self.color), self.type)
class Pen(models.Model):
id = models.AutoField(primary_key=True)
label = models.CharField(max_length=20)
material = models.ForeignKey(Material)
def __unicode__(self):
return "%s_%s" % (str(self.material), self.label)
# admin.py
from django.contrib import admin
from .models import Material, Color, Pen
class PenAdmin(admin.ModelAdmin):
list_display = ('label', 'material', 'get_color',)
fieldsets = (
(None, {
'fields': ('label', 'material')
}),
)
def get_color(self, obj):
return obj.material.color
get_color.short_description = 'Color'
admin.site.register(Pen, PenAdmin)
admin.site.register(Material)
admin.site.register(Color)
我最终没有使用字段集。我想这是用来做简单改动的。以下是完成它的步骤:
-
重写add的url:
url(r'^admin/penshop/pen/add/$', 'penshop.views.add_pen'), url(r'^admin/save_pen/$', 'penshop.views.save_pen'), url(r'^admin/', include(admin.site.urls)),
-
创建一个add_pen.html模板,其中包含您的自定义页面。确保表单包含
{% csrf_token %}
-
在views.py中添加一个入口点来处理表单请求:
@staff_member_required def save_pen(request): if request.method == 'POST': values = request.META.items() label = request.POST.get("label", "") color = request.POST.get("color", "") material = request.POST.get("material", "") if len(label) > 0 and len(color) > 0 and len(material) > 0 and not color.startswith('-') and not material.startswith('-'): import pdb;pdb.set_trace col_obj = Color.objects.filter(color=color)[0] mat_obj = Material.objects.filter(type=material, color=col_obj)[0] pen_obj = Pen(label=label, material=mat_obj) pen_obj.save() return HttpResponseRedirect('/admin/penshop/pen/') else: raise Exception('Bad data. It is not going to be saved!') else: return HttpResponseRedirect('/admin/') return render(request, 'index.html', {'form': form})