获取数据库信息并将其作为XML文件发送到Django

时间:2018-12-07 09:13:11

标签: sql-server django xml

我正在使用Django Web服务,该服务需要处理SQL Server数据库中的数据库信息。我的数据库结构如下:

database diagram taken from SQL-Server's managment studio software.

如您所见,我有一个表,其中包含订单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。我在做什么错了?

1 个答案:

答案 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​​,直到您理解它为止。它实际上很容易使用,但是您一次尝试学习太多就变得很困难。