Django 실전(19): many-to-many 관계 사용자 정의, Atom 구독

19777 단어 django
누군가가 나에게 rails의has 라고 말한 것을 기억한다many:through는'하이라이트'입니다. Django에서 볼 때 이 기능은 언급할 가치가 없습니다. rails의 many-to-many 관련에서는 수동으로 관련표를 만들어야 하고has many:through의'문법'"단지 연결 관계를 사용자 정의하기 위해서입니다. 중간부터 양쪽까지 many-to-one의 모델 클래스를 통해 다대다 연결을 실현합니다. Django에서 many-to-many의 중간 관계표는 자동으로 만들어집니다. 만약에 자신의 모델 클래스를 관계 이미지로 지정하려면 포트를 가져와야 하는 모델 클래스에 ManyToManyField 속성을 추가하고 though 파라미터를 지정해야 합니다. 예를 들어 현재 우리는 이미 이 클래스를 가지고 있습니다.두 가지 many-to-one 관계, Line Item--->Product, Line Item--->Order, Product에서 직접 연결된 Order를 얻으려면 한 줄만 추가하면 됩니다. 최종 Product는 다음과 같습니다.
class Product(models.Model):

    title = models.CharField(max_length=100,unique=True)

    description    = models.TextField()

    image_url = models.URLField(max_length=200)

    price = models.DecimalField(max_digits=8,decimal_places=2)

    date_available = models.DateField()

    orders = models.ManyToManyField(Order,through='LineItem')

 
이후 제품 객체를 통해 해당 제품이 포함된 주문서를 직접 찾을 수 있습니다.
$ python manage.py shell

>>> from depot.depotapp.models import Product

>>> p = Product(id=1)

>>> p.orders



>>> p.orders.all()

[, ]

 
이 관계를 실현하는 목적은 각 제품에 대해'구독'을 생성하여 누가 이 제품을 샀는지 확인하는 것입니다. 저희는 Atom를 형식의 표준으로 사용합니다. 생성된 Atom 발표 형식은 다음과 같습니다.
<?xml version="1.0" encoding="UTF-8"?>

<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">

    <id>tag:localhost,2005:/products/3/who_bought</id>

    <link type="text/html" href="http://localhost:3000/depotapp" rel="alternate"/>

    <link type="application/atom+xml" href="http://localhost:8000/depotapp/product/3/who_bought" rel="self"/>

        <title>    《         》</title>

    <updated>2012-01-02 12:02:02</updated> 

    <entry>

        <id>tag:localhost,2005:Order/1</id>

        <published>2012-01-02 12:02:02</published>

        <updated>2012-01-02 12:02:02</updated>

        <link rel="alternate" type="text/html" href="http://localhost:8000/orders/1"/>

        <title>  1</title>

        <summary type="xhtml">

            <div xmlns="http://www.w3.org/1999/xhtml">

                <p>     </p>                

            </div>

        </summary>

        <author>

            <name>    </name>

            <email>[email protected]</email>

        </author>

    </entry>

    <entry>

        <id>tag:localhost,2005:Order/3</id>

        <published>2012-01-02 12:02:02</published>

        <updated>2012-01-02 12:02:02</updated>

        <link rel="alternate" type="text/html" href="http://localhost:8000/orders/3"/>

        <title>  3</title>

        <summary type="xhtml">

            <div xmlns="http://www.w3.org/1999/xhtml">

                <p></p>                

            </div>

        </summary>

        <author>

            <name>    2</name>

            <email>[email protected]</email>

        </author>

    </entry>

</feed>

 
Atom은 xml 형식으로 되어 있고 우리는 Django REST framework를 빌려 실현할 수 있다고 생각할 수 있지만 이것은 좋은 생각이 아니다. 왜냐하면 REST 프레임워크가 생성한 xml은 그 자체의 형식이 있기 때문에 Atom의 형식과 완전히 다르기 때문이다.만약에 REST 프레임워크를 사용한다면 이를 맞춤형으로 만들어야 한다. 심지어는 자신의rendererer(예를 들어 Atom Rendererr)를 실현해야 하기 때문에 이 프레임워크의 많은 세부 사항을 깊이 이해해야 한다.간단하게 보기 위해서, 우리는 Django의 템플릿으로 실현하는 것을 고려한다.
우선 저희가 URL을 다음과 같이 디자인했습니다.http://localhost:8000/depotapp/product/[id]/who_bought, 먼저 depot/depotapp/urls.py에 urlpatterns 추가:
(r'product/(?P[^/]+)/who_bought$', atom_of_order)

그리고 depot/depotapp/views에서py에서 보기 함수 구현:
def atom_of_order(request,id):

    product = Product.objects.get(id = id)

    t = get_template('depotapp/atom_order.xml')

    c=RequestContext(request,locals())    

    return HttpResponse(t.render(c), mimetype='application/atom+xml')

그중에 우리는 Mimetype을 지정하여 브라우저가 html이 아닌 xml로 되돌아오는 것을 알 수 있도록 했다.마지막 작업은 템플릿을 작성하는 것이다.depot/templates/depotapp/atom_order.xml은 다음과 같습니다.
<?xml version="1.0" encoding="UTF-8"?>

<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">

    <id>tag:localhost,2005:/product/{{product.id}/who_bought</id>

    <link type="text/html" href="{% url depotapp.views.store_view %}" rel="alternate"/>

    <link type="application/atom+xml" href="{% url depotapp.views.atom_of_order product.id %}" rel="self"/>

        <title>    《{{product.title}}》</title>

    <updated>2012-01-02 12:02:02</updated> 

{% for order in product.orders.all %}

    <entry>

        <id>tag:localhost,2005:order/{{order.id}}</id>

        <published>2012-01-02 12:02:02</published>

        <updated>2012-01-02 12:02:02</updated>

        <link rel="alternate" type="text/html" href="{% url depotapp.views.atom_of_order order.id %}"/>

        <title>  {{order.id}}</title>

        <summary type="xhtml">

            <div xmlns="http://www.w3.org/1999/xhtml">

                <p>{{order.address}}</p>                

            </div>

        </summary>

        <author>

            <name>{{order.name}}</name>

            <email>{{order.email}}</email>

        </author>

    </entry>

{% endfor %}

</feed>

 
템플릿으로 Atom 발표를 실현하는 것은 확실히 간단하지 않습니까?

좋은 웹페이지 즐겨찾기