我正在使用Django Web服务,该服务需要处理SQL Server数据库中的数据库信息。我的数据库结构如下:
如您所见,我有一个表,其中包含订单Data_Orders
,该表由Data_Models
表所引用,该表存储了每个订单与相应模型之间的关系。该表还引用Data_ModelColors
的存储ID,该ID用于确定Data_Color
表中颜色的名称。最后,有一个Data_ModelSizes
表,其中包含我最感兴趣的信息,即数量。通过这种设置,我可以指定要添加到每种颜色和尺寸的订单中的模型数量。
现在,我必须将信息从该数据库转换为XML文件,以便以django的形式发送HttpResponse
。如您所见,每个订单还指定了一个要发送给的公司(图的左下方)。每当我收到来自该公司的请求时,就需要为每个公司生成带有订单的XML文件。我创建了一个函数,可以像这样在HttpResponse
中发送XML文件:
def index(request):
template = loader.get_template('orders/testTemplate.xml')
tpcontext = {'orderinfo': 'testordername'}
return HttpResponse(template.render(tpcontext, request))
我目前正在使用测试模板只是为了查看其是否正常工作:
<?xml version="1.0" encoding="UTF-8"?>
<test1>
<testing testid="test">
<test attribute1 = "1">This is a test example to see if django likes XML: {{ orderinfo }}</test>
</testing>
</test1>
,并且我已经确认此设置适用于此模板。但是,我不知道如何将其扩展到我描述的功能。我已经为要创建的XML文件创建了模板:
<?xml version="1.0" encoding="UTF-8"?>
<orders>
{% for order in orderList %}
<order id="{{ order.id }}">
<models>
{% for model in order.models %}
<model id="{{ model.id }}">
<name>{{model.name}}</name>
{% for color in model.colors %}
<color name="'{{color.name}}'">
{% for size in color.sizes %}
<sizeAmount name="'{{size.name}}'">{{size.amount}}</sizeAmount>
{% endfor%}
</color>
{% endfor%}
</model>
{% endfor %}
</models>
</order>
{% endfor %}
</orders>
在这里,我假设我可以只传递一个orderList
对象作为包含订单列表的上下文。然后,每个订单应包含一个模型列表,该列表包含颜色。对于每种颜色,我存储所有大小,然后保存每种大小的数量。
这是我希望输出看起来像的手动预览:
<?xml version="1.0" encoding="UTF-8"?>
<orders>
<order id="13">
<models>
<model id="12">
<name>pants</name>
<color name="blue">
<sizeAmount name="L" >0</sizeAmount>
<sizeAmount name="XL" >3</sizeAmount>
<sizeAmount name="XXL" >11</sizeAmount>
</color>
<color name="red">
<sizeAmount name="L" >2</sizeAmount>
<sizeAmount name="XL" >6</sizeAmount>
<sizeAmount name="XXL" >0</sizeAmount>
</color>
</model>
<model id="13">
<name>jacket</name>
<color name="green">
<sizeAmount name="S" >9</sizeAmount>
<sizeAmount name="L" >11</sizeAmount>
<sizeAmount name="XL" >32</sizeAmount>
<sizeAmount name="XXL" >0</sizeAmount>
</color>
</model>
</models>
</order>
<order id="14">
<models>
<model id="15">
<name>jacket</name>
<color name="green">
<sizeAmount name="S" >0</sizeAmount>
<sizeAmount name="L" >0</sizeAmount>
<sizeAmount name="XL" >0</sizeAmount>
<sizeAmount name="XXL" >5</sizeAmount>
</color>
</model>
</models>
</order>
</orders>
现在我的问题是:如何为该模板提供上下文?我知道您可以传递这样的上下文:tpcontext = {'orderinfo': 'testordername'}
,它将显示在模板中,但是我不知道如何将其应用于我上面描述的数据库结构。
这也是数据库的模型:
class DataColors(models.Model):
id = models.AutoField(db_column='ID', primary_key=True) # Field name made lowercase.
name = models.CharField(db_column='Name', unique=True, max_length=255) # Field name made lowercase.
class Meta:
managed = False
db_table = 'Data_Colors'
class DataCompanies(models.Model):
id = models.AutoField(db_column='ID', primary_key=True) # Field name made lowercase.
name = models.CharField(db_column='Name', max_length=255, blank=True, null=True) # Field name made lowercase.
class Meta:
managed = False
db_table = 'Data_Companies'
class DataModelcolors(models.Model):
colorid = models.ForeignKey(DataColors, models.DO_NOTHING, db_column='ColorID') # Field name made lowercase.
id = models.AutoField(db_column='ID', primary_key=True) # Field name made lowercase.
class Meta:
managed = False
db_table = 'Data_ModelColors'
class DataModeldata(models.Model):
id = models.AutoField(db_column='ID', primary_key=True) # Field name made lowercase.
name = models.CharField(db_column='Name', max_length=255) # Field name made lowercase.
descript = models.CharField(db_column='Descript', max_length=2047, blank=True, null=True) # Field name made lowercase.
class Meta:
managed = False
db_table = 'Data_ModelData'
class DataModeldatacolors(models.Model):
modeldataid = models.ForeignKey(DataModeldata, models.DO_NOTHING, db_column='ModelDataID', primary_key=True) # Field name made lowercase.
colorid = models.ForeignKey(DataColors, models.DO_NOTHING, db_column='ColorID') # Field name made lowercase.
class Meta:
managed = False
db_table = 'Data_ModelDataColors'
unique_together = (('modeldataid', 'colorid'),)
class DataModeldatasizes(models.Model):
modeldataid = models.ForeignKey(DataModeldata, models.DO_NOTHING, db_column='ModelDataID', primary_key=True) # Field name made lowercase.
sizeid = models.ForeignKey('DataSizes', models.DO_NOTHING, db_column='SizeID') # Field name made lowercase.
class Meta:
managed = False
db_table = 'Data_ModelDataSizes'
unique_together = (('modeldataid', 'sizeid'),)
class DataModelsizes(models.Model):
colorid = models.ForeignKey(DataModelcolors, models.DO_NOTHING, db_column='ColorID') # Field name made lowercase.
sizeid = models.ForeignKey('DataSizes', models.DO_NOTHING, db_column='SizeID') # Field name made lowercase.
amount = models.IntegerField(db_column='Amount') # Field name made lowercase.
amountfinished = models.IntegerField(db_column='AmountFinished') # Field name made lowercase.
class Meta:
managed = False
db_table = 'Data_ModelSizes'
class DataModels(models.Model):
modelcolorid = models.ForeignKey(DataModelcolors, models.DO_NOTHING, db_column='ModelColorID') # Field name made lowercase.
orderid = models.ForeignKey('DataOrders', models.DO_NOTHING, db_column='OrderID') # Field name made lowercase.
modeldataid = models.ForeignKey(DataModeldata, models.DO_NOTHING, db_column='ModelDataID') # Field name made lowercase.
id = models.AutoField(db_column='ID', primary_key=True) # Field name made lowercase.
class Meta:
managed = False
db_table = 'Data_Models'
class DataOrdercompanies(models.Model):
orderid = models.ForeignKey('DataOrders', models.DO_NOTHING, db_column='OrderID', primary_key=True) # Field name made lowercase.
companyid = models.ForeignKey(DataCompanies, models.DO_NOTHING, db_column='CompanyID') # Field name made lowercase.
stagenumber = models.IntegerField(db_column='StageNumber') # Field name made lowercase.
class Meta:
managed = False
db_table = 'Data_OrderCompanies'
unique_together = (('orderid', 'companyid'),)
class DataOrders(models.Model):
id = models.AutoField(db_column='ID', primary_key=True) # Field name made lowercase.
ordertimestamp = models.DateTimeField(db_column='OrderTimeStamp', blank=True, null=True) # Field name made lowercase.
finishtimestamp = models.DateTimeField(db_column='FinishTimeStamp', blank=True, null=True) # Field name made lowercase.
name = models.CharField(db_column='Name', max_length=255) # Field name made lowercase.
confirmed = models.IntegerField(db_column='Confirmed') # Field name made lowercase.
class Meta:
managed = False
db_table = 'Data_Orders'
class DataSizes(models.Model):
id = models.AutoField(db_column='ID', primary_key=True) # Field name made lowercase.
name = models.CharField(db_column='Name', unique=True, max_length=255) # Field name made lowercase.
class Meta:
managed = False
db_table = 'Data_Sizes'
编辑:
我正在尝试使其正常工作,但这并不容易。我尝试这样做:
template = loader.get_template('orders/responseTemplate.xml')
ids = DataOrdercompanies.objects.filter(companyid=10).values('orderid')
tpcontext = {'orderList': DataOrders.objects.filter(id__in=ids)}
return HttpResponse(template.render(tpcontext, request))
当前响应XML文件如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<orders>
<order id="16">
<models>
</models>
</order>
</orders>
根据建议,我还将模板更改为:
<?xml version="1.0" encoding="UTF-8"?>
<orders>
{% for order in orderList %}
<order id="{{ order.id }}">
<models>
{% for model in order.models.all %}
<model id="{{ model.id }}">
<name>{{model.name}}</name>
{% for color in model.colors.all %}
<color name="'{{color.name}}'">
{% for size in color.sizes.all %}
<sizeAmount name="'{{size.name}}'">{{size.amount}}</sizeAmount>
{% endfor%}
</color>
{% endfor%}
</model>
{% endfor %}
</models>
</order>
{% endfor %}
</orders>
在上下文中似乎给了我一个空的orderList。我在做什么错了?
答案 0 :(得分:1)
您的模型很难阅读和使用;我意识到它们可能是从现有的db模式自动生成的,但是您需要对其进行整理以使其可用。
从您的角度来看,最重要的事情是识别何时具有多对多关系(例如在Ordercompany中),并使其明确。但是,您还需要进行一些重命名以遵循Django约定:首先从所有模型名称中删除Data
前缀,使用正确的InitialCaps格式,并使它们为单数。接下来,从外键中删除id
后缀,并为所有字段提供lower_case_with_underscore格式名称。所以:
class Color(models.Model):
...
class Company(models.Model):
orders = models.ManyToManyField('Order', through='OrderCompany')
...
# what's the point of this table?
class ModelColor(models.Model):
color = models.ForeignKey(Color, models.DO_NOTHING, db_column='ColorID')
...
class ModelData(models.Model):
colors = models.ManyToManyField('Color', through='ModelDataColor')
sizes = models.ManyToManyField('Size', through='ModelDataSize')
...
class ModelDataColor(models.Model):
model_data = models.ForeignKey(ModelData, models.DO_NOTHING, db_column='ModelDataID', primary_key=True)
color = models.ForeignKey(Color, models.DO_NOTHING, db_column='ColorID')
...
class ModelDataSize(models.Model):
model_data = models.ForeignKey(ModelData, models.DO_NOTHING, db_column='ModelDataID', primary_key=True)
size = models.ForeignKey('Size', models.DO_NOTHING, db_column='SizeID')
...
class ModelSize(models.Model):
color = models.ForeignKey(ModelColor, models.DO_NOTHING, db_column='ColorID')
size = models.ForeignKey('DataSize', models.DO_NOTHING, db_column='SizeID')
...
class Model(models.Model):
model_color = models.ForeignKey(ModelColor, models.DO_NOTHING, db_column='ModelColorID')
order = models.ForeignKey('Order', models.DO_NOTHING, db_column='OrderID')
model_data = models.ForeignKey(ModelData, models.DO_NOTHING, db_column='ModelDataID')
...
class OrderCompany(models.Model):
order = models.ForeignKey('Order', models.DO_NOTHING, db_column='OrderID', primary_key=True)
company = models.ForeignKey(Company, models.DO_NOTHING, db_column='CompanyID')
stage_number = models.IntegerField(db_column='StageNumber')
...
class Order(models.Model):
...
class Size(models.Model):
...
(我不了解您的所有关系,所以我可能没有所有这些权利。)
因此,现在您在“订单”和“公司”之间具有适当的关系,您可以直接查询以下内容:
company = Company.objects.get(id=10) # remember to use `get` for a single item
order_list = company.orders.all()
并将其传递给模板。
请注意,您仍未在模板中使用关系的实际名称或反向关系。由于模型和订单之间的关系未定义明确的related_name,因此默认值为model_set
;或者,如果您坚持使用自己的原始姓名,则为datamodels_set
。遵循这种关系时,您需要使用它:
{% for model in order.model_set.all %}
类似地,从模型到颜色的ForeignKey在我的版本中称为model_color
,在您的版本中称为modelcolorid
;再次,这就是您需要使用的名称:
{model.model_color.all%中颜色的%}
对于Django新手来说,这是一组非常复杂的模型-总体而言是一项复杂的任务。您可能应该从较小的模型开始,只有几个模型,然后尝试使用API,直到您理解它为止。它实际上很容易使用,但是您一次尝试学习太多就变得很困难。