Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django How can i split string using template tag

Tags:

python

django

Hello I want to know that how can I split string of dictionary values

This is my crawler which is returns dictionary data looks like

data = {
    {0:'http://..., product name, product price'},
    {1:'http://...2, product name2, product price2'},
    {N:'http://...2, product name2, product price n'}
}

I want to split these data by comma like,

for value in data.values():
     href, product_name, product_price = str(value).split(",")

in Django

This is my crawler.py

import requests
from urllib import parse
from bs4 import BeautifulSoup


def spider(item_name):
    url_item_name = parse.quote(item_name.encode('euc-kr'))

    url = 'http://search.11st.co.kr/SearchPrdAction.tmall?method=getTotalSearchSeller&isGnb=Y&prdType=&category=&cmd=&pageSize=&lCtgrNo=&mCtgrNo=&sCtgrNo=&dCtgrNo=&fromACK=recent&semanticFromGNB=&gnbTag=TO&schFrom=&schFrom=&ID=&ctgrNo=&srCtgrNo=&keyword=&adUrl=&adKwdTrcNo=&adPrdNo=&targetTab=T&kwd=' + url_item_name
    resp = requests.get(url)
    resp.raise_for_status()

    resp.encoding='euc-kr'
    plain_text = resp.text

    soup = BeautifulSoup(plain_text, 'lxml')
    mytag = soup.find_all(True, {"class": ["sale_price", "list_info"]})
    #for link in soup.select('div.list_info p.info_tit a') :
    data = {}
    count = -1;
    for link in mytag:
        if(link.find('a')):
            count+=1
            href = link.find('a').get('href')
            product_name = link.find('a').string
            data[count] = str(href) + ", " + str(product_name)
        else:
            product_price = link.string
            if(product_price):
                data[count] = data[count] +", " + str(product_price)

    for value in data.values():
        print(value)
    resp.close()

    return data

and this is my views

def post_shop_list(request):
    posts = spider("product name")
    return render(request, 'blog/post_list.html',{'posts' : posts})

and this is my post_list.html

{% for key, value in posts.items %}
    <div>
        <td>{{key}}</td>
        <p>product name :{{value}}</p>
        <h1><a href=href> </a></h1>
        <p>{{ product_price|linebreaksbr}}</p>
    </div>
{% endfor %}

Thank you .. !!

like image 680
Minsoo kim Avatar asked Dec 05 '17 14:12

Minsoo kim


People also ask

What is the use of template tag in Django?

Django Code The template tags are a way of telling Django that here comes something else than plain HTML. The template tags allows us to to do some programming on the server before sending HTML to the client.

What is split in Django?

The split() method splits a string into a list. You can specify the separator, default separator is any whitespace.

Can I use Django template tags in Javascript?

You can't use Django's template tags from your Javascript code if that's what you mean. All the Django variables and logic stop existing after the template has been rendered and the HttpResponse has been sent to the client.


2 Answers

Create custom template filter

from django import template

register = template.Library()

@register.filter(name='split')
def split(value, key):
  """
    Returns the value turned into a list.
  """
  return value.split(key)

In Django template you can use it like.

# assuming value = "url, product_name, product_price"
# and you have always these three comma separated items in sequence
{% for key, value in posts.items %}
   <tr>
      {% with value|split:"," as details %}
         {% for p in details %}
            <td>{{ p }}</td>
         {% endfor %}
      {% endwith %} 
   </tr>    
{% endfor %}

UPDATE

You have to also make entry of your tag file in TEMPLATE list in libraries keyword.

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            str(APPS_DIR.path('templates')),
        ],
        'OPTIONS': {

            'loaders': [
                ...
            ],

            'context_processors': [
                ...
            ],
            'libraries':{
               # make your file entry here.
               'filter_tags': 'app.templatetags.filter',
            }
        },
    },
]

and then load this tag to top of your html file where you want to use split filter

{% load filter_tags %}
like image 157
Satendra Avatar answered Nov 10 '22 20:11

Satendra


i'd advise against doing these sort of things in templates. you end up having half of your view logic embedded in them. i suggest doing something like this in your view or better yet your crawler:

products = []
for key, value in posts.items():
    product = value.split(',')
    # product = [href,name,price]
    product_entry = {
            'key' : key,
            'name' : product[1],
            'href' : product[0],
            'price' : product[2]
    }
    products.append(product_entry)

You end up with a nice array of dicts, hand it out to the template and in there you simply iterate over it and read the elements fields.

{% for item in products %}
    <td>{{ item.key }}</td>
    <p>product name :{{ item.name}}</p>
    <h1><a href={{ item.href }}> </a></h1>
    <p>{{ item.price }}</p>
{% endfor %}

Alternatively, create a custom template-tag as described here

like image 25
joppich Avatar answered Nov 10 '22 20:11

joppich