2015-12-19 2 views
0

У меня есть модель с несколькими полями, которые выглядят следующим образом:Подготовка данных XML для десериализации в Django

class XMLData(models.Model): 
    name = models.CharField() 
    description = models.CharField() 
    price = models.CharField() 

и XML-данных, завернутые в строку, данные XML выглядеть следующим образом:

<Root> 
    <Header> 
     <information>info</information> 
    </Header> 
    <Main> 
     <Product> 
     <Name>name1</Name> 
     <Description>description1</Description> 
     <Price>1</Price> 
     </Product> 
     <Product> 
     <Name>name2</Name> 
     <Description>description2</Description> 
     <Price>2</Price> 
     </Product> 
    </Main> 
</Root> 

Мои Вопрос: должен ли я заменять дочерние узлы Product на родительский узел и должен ли я переименовывать теги Name, Description, Price - name, description, price?

Я попытался десериализация с помощью этого кода:

for product in serializers.deserialize("xml", xmldata): 
    savedata = XMLData(product) 
    savedata.save() 

я надеялся, что будет расти некоторых ошибок и я бы понять, что делать дальше, но не было никаких ошибок и данные XML не сохранить в базу данных ,

Надеюсь, вы поймете мою проблему и благодарите вас за ответ.

+1

Здесь нет никакой магии. Django не может десериализовать любой XML, который вы хотите. Он может десериализовать только формат, описанный в [документации] (https://docs.djangoproject.com/en/1.9/topics/serialization/#xml). И ваш XML не соответствует ожидаемому формату. Вы должны изучить общие инструменты анализа XML (например, ['lxml'] (http://lxml.de/)) и вручную создавать модели из проанализированных данных. –

+0

Благодарим за ответ, пожалуйста, сообщите свой ответ. Чтобы закрыть этот вопрос –

+0

Существует лучший ответ от @ abu-ashraf-masnun. Не стесняйтесь принять его вместо этого. –

ответ

3

Возможно, вас интересует только информация о продукте. В этом случае Product будет лучшим именем модели, чем XMLData.

Django serializers не поможет, так как ваши данные не в правильном формате. Однако вы можете десериализовать с помощью lxml. Код взят из: Converting xml to dictionary using ElementTree

from xml.etree import cElementTree as ET 
from collections import defaultdict 

def etree_to_dict(t): 
    d = {t.tag: {} if t.attrib else None} 
    children = list(t) 
    if children: 
     dd = defaultdict(list) 
     for dc in map(etree_to_dict, children): 
      for k, v in dc.iteritems(): 
       dd[k].append(v) 
     d = {t.tag: {k:v[0] if len(v) == 1 else v for k, v in dd.iteritems()}} 
    if t.attrib: 
     d[t.tag].update(('@' + k, v) for k, v in t.attrib.iteritems()) 
    if t.text: 
     text = t.text.strip() 
     if children or t.attrib: 
      if text: 
       d[t.tag]['#text'] = text 
     else: 
      d[t.tag] = text 
    return d 

e = ET.XML(''' 
<Root> 
    <Header> 
     <information>info</information> 
    </Header> 
    <Main> 
     <Product> 
     <Name>name1</Name> 
     <Description>description1</Description> 
     <Price>1</Price> 
     </Product> 
     <Product> 
     <Name>name2</Name> 
     <Description>description2</Description> 
     <Price>2</Price> 
     </Product> 
    </Main> 
</Root> 
''') 

from pprint import pprint 

d = etree_to_dict(e) 

pprint(d) 

Теперь, вместо симпатичной печати, мы можем непосредственно хранить продукты:

d = etree_to_dict(e) 

products = d['Root']['Main']['Product'] 

for p in products: 
    product = Product() 
    p.name = p['Name'] 
    p.description = p['Description'] 
    p.price = p['Price'] 

    p.save() 

Это должно хранить продукты в базе данных.