2

I am very new to Django and implemented a post-api call by watching couple of tutorials and one of the fields gets a list of dictionaries, want to access the key value pair in Django template, instead it is taking char by char, do I have to change the definition in models.py for the Message field or use JSON parser in views.py ?how to solve this problem?

models.py

class Leads(models.Model):
    Name = models.CharField(max_length=50)
    Mobile = models.CharField(max_length=13)
    Email = models.CharField(max_length=50)
    Message = models.CharField(max_length=300)
    created_on = models.DateTimeField(default=datetime.now())
    modified_on = models.DateTimeField(default=datetime.now())

Example input for above api call will be:

   Name = rakesh
   Mobile = 1234567890
   Email = email@mail.com
   Message = [{'key': 'some text', 'value': 'some value'}, {'key': 'some text', 'value': 'some value'}]

This is how my api records are getting stored in Database

views.py

@api_view(["POST"])
def userLeads(request):
    try:
        if request.method == 'POST':
            Name = request.data['Name']
            Email = request.data['Email']
            Mobile = request.data['Mobile']
            Message = request.data['Message']   

            datainsertion = models.Leads(Name = Name, Email = Email, Mobile = Mobile,Message= Message)
            datainsertion.save()
            content = {'Leads_Status': 'Created'}
            return Response(content, status=status.HTTP_200_OK)
    except Exception as e:
        print (e)
        content = {'Order_Status': 'Failed'}
        return Response(content, status=status.HTTP_424_FAILED_DEPENDENCY)

Views.py

def chat_Leads_view(request):

    user_list = models.Leads.objects.all().order_by('-id')
    myFilter = UserFilter(request.GET, queryset=user_list)
    user_list = myFilter.qs
           
    page = request.GET.get('page', 1)
    paginator = Paginator(user_list, 5)
    
    try:
        users = paginator.page(page)
        
    except PageNotAnInteger:
        users = paginator.page(1)
        
    except EmptyPage:
        users = paginator.page(paginator.num_pages)
    
    segment = 'leads'
    context = {
        "users": users,
        "segment":segment,
        "myFilter":myFilter
        
    }   
    
    return render(request, "leads.html", context)

template.html

   {%for user in users %}
     <tr>                                                
         <td>{{user.Name}}</td>
         <td>{{user.Mobile}}</td>
         <td>{{user.Email}}</td>
         <td>{{user.Message}}</td>
     </tr>
   {%endfor%}

If I try like above then the output is

rakesh  1234567890  emaik@mail.com  [{'key': 'some text', 'value': 'some value'}, {'key': 'some text', 'value': 'some value'}]

If I add another loop for Message field then the Message field is not showing any output:

   {%for user in users %}
     <tr>                                                
         <td>{{user.Name}}</td>
         <td>{{user.Mobile}}</td>
         <td>{{user.Email}}</td>
   {%for i in user.Message %}
         <td>{{i.key}}</td>
         <td>{{i.value}}</td>
   {%endfor%}
     </tr>
   {%endfor%}

Output: displaying string by string

rakesh  1234567890  emaik@mail.com  

If I try like this then:

{%for user in users %}
         <tr>                                                
             <td>{{user.Name}}</td>
             <td>{{user.Mobile}}</td>
             <td>{{user.Email}}</td>
       {%for i in user.Message %}
             <td>{{i}}</td>
       {%endfor%}
         </tr>
       {%endfor%}

Output:

rakesh  1234567890  emaik@mail.com  [ { ' k e y ' : ' s o m e t e x t ' , ' v a l u e ' : 's o m e v a l u e ' }, { ' k e y ' :  ' s o m e t e x t ' , ' v a l u e ' : ' s o m e v a l u e ' } ]

The way I want in Django template is:

rakesh  1234567890  emaik@mail.com  key:value 
                                    key: value
Bharath
  • 204
  • 1
  • 14

1 Answers1

1

Your message is not a list of dictionaries. It is simply a string that contains some data that looks like a list of dictionaries.

You probably should change it to a JsonField [Django-doc]:

class Leads(models.Model):
    Name = models.CharField(max_length=50)
    Mobile = models.CharField(max_length=13)
    Email = models.CharField(max_length=50)
    Message = models.JSONField()
    created_on = models.DateTimeField(auto_now_add=True)
    modified_on = models.DateTimeField(auto_now=True)

and re-populate the database with data. In that case accessing the message will indeed return a list of dictionaries that you can then render with:

<td>
{% for item in user.Message %}
    {{ item.key }}<br>
    {{ item.value }}
{% endfor %}
</td>

Note: normally a Django model is given a singular name, so Lead instead of Leads.


Note: normally the name of the fields in a Django model are written in snake_case, not PascalCase, so it should be: message instead of Message.


Note: Django's DateTimeField [Django-doc] has a auto_now_add=… parameter [Django-doc] to work with timestamps. This will automatically assign the current datetime when creating the object, and mark it as non-editable (editable=False), such that it does not appear in ModelForms by default.

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555