django AttributeError: 'str' object has no attribute 'field' - ajax

I am getting this error while submitting an ajax request using django.
The funny thing is if I execute these commands by hand when the debugger hits it works.
Here is the views.py
def lhr_search_custodians(request):
print request
print request.GET
print "blah"
# pdb.set_trace()
if request.method == 'GET':
search_text = request.GET.get('search_text')
else:
search_text = ''
custodians = Person.objects.filter(last_name__contains=search_text)
context = {'custodians': custodians}
return render(request, 'corpsec/legalholdrequests/create.html', context)
Here is the javascript query.js
$(function () {
$('#custodian_search').keyup(function (){
console.log("search fired!!!");
$.ajax({
url: "new/search_custodians",
type: "GET",
data: {
'search_text' : $('#custodian_search').val(),
'csrfmiddlewaretoken' : $("input[name=csrfmiddlewaretoken]").val()
},
success : searchSuccess,
dataType: 'html',
error: function(xhr, errmsg, err) {
$('#results');
}
});
});
});
function searchSuccess(data, textStatus, jqXHR) {
$('$search_results').html(data);
}
this is the template create.html
{% extends "blackbox/show.html" %}
{% load static from staticfiles %}
{% load formtags %}
{% block title %}
New Legal Hold Request | {{ block.super }}
{% endblock title %}
{% block javascript %}
{{ block.super }}
{% endblock javascript %}
{% block show_header_title %}
<h4>
New Legal Hold Request
</h4>
{% endblock show_header_title %}
{% block tab_menu %}
<li class="tab">
<a id="id_modal_matter"
href="#matter">
Matter
</a>
</li>
<li class="tab">
<a id="id_modal_custodians"
href="#custodians">
Custodians
</a>
</li>
<li class="tab">
<a id="id_modal_electronic_databases"
href="#databases">
Electronic Databases
</a>
</li>
<li class="tab">
<a id="id_modal_collection"
href="#collection">
Collection
</a>
</li>
{% endblock tab_menu %}
{% block tab_content %}
<form action="/corpsec/legalholdrequests/new"
role="form"
method="post">
<span id="csrfmiddlewaretoken">{% csrf_token %}</span>
{% if form.errors %}
<div class="alert alert-dismissable alert-danger">
<button type="button" class="close" data-dismiss="alert">×</button>
<strong>Error.</strong> Please correct the following errors:
<small>{{ form.errors }}</small>
</div>
{% endif %}
<div class="row">
<div class="col s12">
<button id="id_form_submit"
type="submit"
class="btn right">
Submit
</button>
</div>
</div>
<div class="row">
<div id="matter" class="col s12">
<div class="row">
<div class="col s12 m8 offset-m2">
<div class="card">
<div class="card-content">
{{ form.matter_name|bsf_field }}<br/>
{{ form.matter_number|bsf_field }}<br/>
{{ form.matter_category|bsf_field }}<br/>
{{ form.priority_rating|bsf_field }}<br/>
{{ form.preservation|bsf_field }}<br/>
{{ form.issue_start|bsf_field }}<br/>
{{ form.issue_stop|bsf_field }}<br/>
{{ form.market_area|bsf_field }}<br/>
{{ form.attorney|bsf_field }}<br/>
{{ form.paralegal|bsf_field }}<br/>
{{ form.risk_manager|bsf_field }}<br/>
{{ form.category|bsf_field }}<br/>
</div>
</div>
</div>
</div>
</div>
<div id="custodians" class="col s12">
<div class="row">
<!-- search card -->
<div class="col s12 m3">
<div class="card">
<div class="card-content">
<span class='card-title'>Search Custodians</span>
<script src="{% static 'js/ldap-lookup.js' %}" type="text/javascript"></script>
<script src="{% static 'js/custodian_query.js' %}" type="text/javascript"></script>
{% csrf_token %}
<input type="text" id='custodian_search' name="search">
</div>
</div>
</div>
<!-- results section placeholder for now-->
<div class="col s12 m6">
<div class="card">
<div class="card-content">
<span class="card-title"> Results</span>
<ul id="search_results">
</ul>
</div>
</div>
</div>
<!-- action section -->
<div class="col s12 m3">
<div class="card">
<div class="card-content">
<span class="card-title">Action</span>
</div>
</div>
</div>
</div>
</div>
<div id="databases" class="col s12">
<div class="row" class='database_1'>
<div class="col s12 m8 offset-m2">
<div class="card">
<div class="card-content">
<div class="row">
{{ database_and_criteria_1.database|bsf_field }}<br/>
{{ database_and_criteria_1.criteria|bsf_field }}<br/>
</div>
</div>
<div class="card-action">
<button class='btn waves-effect waves-light' id='show_next_button' type="button" name="button">Add Database and Criteria</button>
</div>
</div>
</div>
</div>
<div class="row" id='database_2' style="display: none;">
<div class="col s12 m8 offset-m2">
<div class="card">
<div class="card-content">
<div class="row">
{{ database_and_criteria_2.database|bsf_field }}<br/>
{{ database_and_criteria_2.criteria|bsf_field }}<br/>
</div>
</div>
<div class="card-action">
<button class='btn waves-effect waves-light' id='show_next_button_2' type="button" name="button">Add Database and Criteria</button>
<button class='btn waves-effect waves-light red' id='remove_db_criteria_2' type="button" name="button">Remove</button>
</div>
</div>
</div>
</div>
<div class="row" id='database_3' style="display: none;">
<div class="col s12 m8 offset-m2">
<div class="card">
<div class="card-content">
<div class="row">
{{ database_and_criteria_3.database|bsf_field }}<br/>
{{ database_and_criteria_3.criteria|bsf_field }}<br/>
</div>
</div>
<div class="card-action">
<button class='btn waves-effect waves-light red' id='remove_db_criteria_3' type="button" name="button">Remove</button>
</div>
</div>
</div>
</div>
</div>
<div id="collection" class="col s12">
<div class="row">
<div class="col s12 m8 offset-m2">
<div class="card">
<div class="card-content">
<h4>Files<br/></h4>
{{ collection_form.email|bsf_field }}<br/>
{{ collection_form.netshare|bsf_field }}<br/>
{{ collection_form.computer_data|bsf_field }}<br/>
{{ collection_form.group_shares|bsf_field }}<br/>
{{ collection_form.pst_files|bsf_field }}<br/>
{{ collection_form.mobile_device|bsf_field }}<br/>
{{ collection_form.drive_cam_event_number|bsf_field }}<br/>
{{ collection_form.other_data_instructions|bsf_field }}<br/>
<h4>Processing</h4><br/>
{{ collection_form.processing_deadline|bsf_field }}<br/>
{{ collection_form.emails_attachments|bsf_field }}<br/>
{{ collection_form.everything|bsf_field }}<br/>
{{ collection_form.dedupe_matter|bsf_field }}<br/>
{{ collection_form.dedupe_custodian|bsf_field }}<br/>
{{ collection_form.keywords|bsf_field }}<br/>
{{ collection_form.archive_start|bsf_field }}<br/>
{{ collection_form.archive_stop|bsf_field }}<br/>
{{ collection_form.review_platform_external|bsf_field }}<br/>
{{ collection_form.delivery_instructions|bsf_field }}<br/>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
<script type="text/javascript">
$('#show_next_button').click(function() {
document.getElementById('database_2').style.display = 'block';
});
$('#show_next_button_2').click(function() {
document.getElementById('database_3').style.display = 'block';
});
$('#remove_db_criteria_2').click(function() {
document.getElementById('database_2').style.display = 'none';
});
$('#remove_db_criteria_3').click(function() {
document.getElementById('database_3').style.display = 'none';
});
</script>
{% endblock tab_content %}

Related

Laravel query return wrong data

QUERY:
$recent_posts = Blog::join("categories",'categories.id', '=', 'blogs.category_id')
->where('categories.status', 1)
->orderBy('blogs.id', 'desc')
->take(3)
->get();
Both tables had a created_at column.
At frontend im using this to retrieve the data:
<div class="row justify-content-center">
#foreach ($recent_posts as $recent_post)
<div class="col-md-6 col-lg-4 latest-blog-resp">
<div class="blog-item">
<div class="blog-img">
<a href="{{ url('blog/'.$recent_post->slug) }}">
#if ($recent_post->blog_image == '')
<img src="{{ asset('fibonacci/adminpanel/assets/img/dummy/no_image.jpg') }}" class="img-fluid round-item" alt="blog image">
#else
<img src="{{ asset('fibonacci/adminpanel/assets/img/blog/thumbnail1/'.$recent_post->blog_image) }}" class="img-fluid round-item" alt="blog image">
#endif
</a>
</div>
<div class="blog-inner">
<div class="blog-meta">
<span class="mr-2">
<i class="mdi mdi-calendar-account-outline"></i>{{ __('frontend.by_admin') }}
</span>
<span>
<i class="mdi mdi-calendar-range"></i>{{Carbon\Carbon::parse($recent_post->created_at)->isoFormat('MMMM')}} {{Carbon\Carbon::parse($recent_post->created_at)->isoFormat('DD')}}
</span>
</div>
<h5 class="blog-title">
{{ $recent_post->title }}
</h5>
<p class="blog-desc">{{ $recent_post->short_description }}</p>
<a href="{{ url('blog/'.$recent_post->slug) }}" class="blog-more-link">
{{ __('frontend.read_more') }} <i class="fa fa-angle-right ml-2"></i>
</a>
</div>
</div>
</div>
#endforeach
#if (count($recent_posts) === 3)
<div class="col-12 text-center margin-top-30">
<div class="btn-group">
<a href="{{ url('blog') }}" class="default-button">
{{ __('frontend.view_all') }}
</a>
</div>
</div>
#endif
</div>
THE PROBLEM:
$recent_post->created_at returns the category table creation (created_at) date but we expect to receive the blog table result as created_as (like a post creation data).
Thanks in advance!
Specify your fields in a select clause.
$recent_posts = Blog::select(
'blogs.slug',
'blogs.blog_image',
'blogs.title',
'blogs.short_description',
'blogs.created_at'
)
->join('categories', 'categories.id', 'blogs.category_id')
->where('categories.status', 1)
->orderByDesc('blogs.id')
->take(3)
->get();

Using 2 Controller Functions in a View in Laravel

I want to have two loops in my view, so I wrote these two functions
public function index()
{
$books = Book::orderBy('created_at', 'desc')->take(10)->get();
return view('bookpage')->with('books', $books);
}
public function loggedin()
{
$books = Book::orderBy('RAND()')->take(1)->get();
return view('bookpage')->with('books', $books);
}
In the view I have
<!--First Loop -->
#foreach($books as $book)
<div class="col-md-6">
<div class="out-box">
<h2>{{ $book->name }}</h2>
<h3>{{ $book->author->name }}</h3>
<br>
Start Reading<br><br>
<img src="assets/img/cart-buy.png" width="13px"/> Buy
</div>
</div>
</div>
</div>
<div class="col-md-6">
<input id="aboutbook" type="radio" name="tabs" checked>
<label for="aboutbook" class="aboutbook">About This Book</label>
<input id="bookreview" type="radio" name="tabs">
<label for="bookreview" class="bookreview">Reviews</label>
<hr style="background-color:black;">
<section style="padding-top:5px;" id="bookabout" >
<div class="row">
<div class="col-md-12">
<p>{{ $book -> about }}</p>
<h1>About the Author</h1>
</div>
</div>
<div class="row">
<div class="col-sm-4 col-md-3 col-6">
<img src="assets/img/Ellipse.png" class="rounded-circle" width="120px">
</div>
<div class="col-sm-4 col-md-4 col-6">
<h1>{{ $book->author->name }}</h1>
<h4>{{ $book->author->about }}</h4>
</div>
<div class="col-sm-4 col-md-5">
<div id="learnbtn">
Learn More
</div>
</div>
</div>
</section>
<section style="padding-top:5px;" id="bookabout1" >
jjjjjjj
</section>
</div>
</div>
</div>
#endforeach
</section>
<!--Second Loop -->
#foreach($books as $book)
#if($book->recommended === 1)
<div class="col-1-5">
<div class="home-catalog-image">
<a href="{{ $book->image_url }}" target="_blank">
<!-- <img src="{{ $book->image }}" alt="trending image" /> -->
<img src="{{ $book->image_url }}" class="img-responsive" alt="{{ $book->image_url }}">
</a>
<!-- <img src="{{ asset('/books/'.$book->image) }}" alt="trending image" /> -->
</div>
<p class="author">{{ $book->author->name }}</p>
<h1 class="book-title">{{str_limit($book -> name, 20) }}</h1>
</div>
#endif
#endforeach
In my web.php
Route::get('/', 'WelcomeController#index')->name('welcome');
I want to call another function in the view, although I know the method is wrong, I don't know how to go about it.
You don't have to create two different method for logged in user just use
public function index()
{
if(auth()->user()) {
$books = Book::orderBy('RAND()')->take(1)->get();
} else $books = Book::orderBy('created_at', 'desc')->take(10)->get();
return view('bookpage')->with('books', $books);
}
in view file use
#auth
//code for logged in user
#else
//code for guest user
#endauth
I was able to solve my problem like this
public function loggedin()
{
$data = array();
$data['recommends'] = Book::where('recommended', 1)->take(10)->get();
$data['latests'] = Book::orderBy('created_at', 'desc',)->where('recommended', 0)->take(10)->get();
$data['logged'] = Book::all()->random(1);
return view('index-logged', compact("data"));
}
In my view, I did
#foreach($data['logged'] as $log)
<h1>{{ $log->author->name }}</h1>
<h4>{{ $log->author->about }}</h4>
#endforeach
#foreach($data['recommends'] as $recommend)
<p class="author">{{ $recommend->author->name }}</p>
<h1 class="book-title">{{str_limit($recommend -> name, 20) }}</h1>
#endforeach
#foreach($data['latests'] as $latest)
<p class="author">{{ $latest->author->name }}</p>
<h1 class="book-title">{{str_limit($latest -> name, 20) }}</h1>
#endforeach

Undefined variable: product in blade view

<div class="row">
#foreach($product as $data)
<div class="col-lg-4 col-md-6 mb-4">
<div class="card h-100">
<img src="{{ asset('image/product_image/'.$data->product_image) }}" alt="photo">
<div class="card-body">
<h4 class="card-title">
{{ $data->product_name }}
</h4>
<h5>{{ $data->product_price }}</h5>
<p class="card-text">{{ $data->product_description }}</p>
</div>
<div class="card-footer">
<small class="text-muted">★ ★ ★ ★ ☆</small>
</div>
</div>
</div>
#endforeach
<!-- /.row -->
</div>
First collect what you want in the controller. It could be something like this:
$product = Product::all();
And then you must send the product variable to the view. Something like this:
return view('path.to.view', compact('product'));
By the way. it's better to use plural form products.
You can add the code in the blade to retrieve all the products from the product model
<div class="row">
#php
$product = App\Product::all();
#endphp
#foreach($product as $data)
<div class="col-lg-4 col-md-6 mb-4">
<div class="card h-100">
<img src="{{ asset('image/product_image/'.$data->product_image) }}" alt="photo">
<div class="card-body">
<h4 class="card-title">
{{ $data->product_name }}
</h4>
<h5>{{ $data->product_price }}</h5>
<p class="card-text">{{ $data->product_description }}</p>
</div>
<div class="card-footer">
<small class="text-muted">★ ★ ★ ★ ☆</small>
</div>
</div>
</div>
#endforeach
<!-- /.row -->
</div>
Your code should be like this
Controller's index method,
public function index()
{
$product = Product::all();
return view('path', compact('product'));
}

How to get next pages in load more django

I get data using ajax with button load more, and if it's not have next pages, it will render "all data has been displayed"
index.html
<div class="panel-body">
<div id="display-data">
<span id="loading-help">Loading data. . .</span>
</div>
</div>
<script>
var page = 1
$(document).ready(function(){
$.get("{% url 'account:profile' %}?param=get_data&page="+page,
function(data){
$("#display-data").append(data)
$("#loading-help").remove()
page++
})
</script>
data-ajax.html
{% for data in datas %}
<div class="list-trx-data">
<div class="row align-items-center">
<div class="col-md-8">
<div class="row align-items-center">
<div class="col-md-4 col-sm-12 col-12 data-date">
{{data.get_formatted_date}}</div>
<div class="col-md-8 col-sm-12 col-12 data-name">
{{data.get_data}}</div>
</div>
</div>
<div class="col-md-4">
<div class="row align-items-center">
<div class="col-md-6 col-8 data-amount">
{{data.get_formatted_amount}}</div>
<div class="col-md-6 col-4 ">
<div class="data-progress">
<div class="pg-bar" style="width:
{{data.get_data.get_progress_str}}"></div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
{% if datas.has_other_pages %}
{% if datas.has_next %}
<a href="javascript:void(0)" class="btn btn-ghost btn-block mt-2"
id="load-more-btn">Load More</a>
{% else %}
<a href="javascript:void(0)" class="btn btn-ghost btn-block mt-2"
id="load-more-btn">All data has been displayed</a>
{% endif %}
{% endif %}
<script>
$("#load-more-btn").click(function(){
$.get("{% url 'account:profile' %}?param=get_data&page="+page,
function(data){
$("#display-data").append(data)
page++
})
})
</script>
I have try it but it's render all button
before click load more
after click load more
how to fix it ?
Firstly, don't place javascript in the data-ajax.html. All the javascript code should be placed in index.html, where all the logics need to be implemented. If there is not other data, data-ajax.html returned should be empty.
data-ajax.html
{% for data in datas %}
<div class="list-trx-data">
<div class="row align-items-center">
<div class="col-md-8">
<div class="row align-items-center">
<div class="col-md-4 col-sm-12 col-12 data-date">
{{data.get_formatted_date}}</div>
<div class="col-md-8 col-sm-12 col-12 data-name">
{{data.get_data}}</div>
</div>
</div>
<div class="col-md-4">
<div class="row align-items-center">
<div class="col-md-6 col-8 data-amount">
{{data.get_formatted_amount}}</div>
<div class="col-md-6 col-4 ">
<div class="data-progress">
<div class="pg-bar" style="width:
{{data.get_data.get_progress_str}}"></div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
{% if datas.has_other_pages %}
{% if datas.has_next %}
<a href="javascript:void(0)" class="btn btn-ghost btn-block mt-2"
id="load-more-btn">Load More</a>
{% endif %}
In your index.html, check if ajax call returned anything, if not, then change button text, else, remove the button element, since your data-ajax.html already has button based on {% if datas.has_other_pages %}.
index.html
<div class="panel-body">
<div id="display-data">
<span id="loading-help">Loading data. . .</span>
</div>
</div>
<script>
$(document).ready(function(){
var page = 1; //page defined in $(document).ready()
function getData(){
$.get("{% url 'account:profile' %}?param=get_data&page="+page, function(data){
$("#loading-help").remove();
if (data){
// data was received
$("#loading-help").remove();
$("#load-more-btn").remove(); # remove the load button if data is there.
$("#display-data").append(data);
page++;
} else {
$("#load-more-btn").text("All data has been displayed"); # else, change button text.
}
});
}
getData(); //Load data for the first time.
$("#load-more-btn").click(function(){
getData(); //Load data on button click.
});
</script>

Get template block contents and call from ajax

I'm using django 1.9 and python 3. My english also isn't the best, so excuse the question if it is formulated bad.
I'm working on making my website a single-page application. I need to get the {% block %} contents of a given template, and then send that as a HttpResponse so that ajax can pick it up and inject it into the page.
I've tried using the answer from this question: Django - how to get the contents of a {% block %} tag from a template
But upon trying to fetch the contents of a block in my view like so:
response_data[content] = get_block_source('profile/login.html', 'content')
if request.is_ajax():
return HttpResponse(
json.dumps(response_data),
content_type="application/json"
)
I just get this error from django, no matter what I do:
ValueError at /login/ Template block content not found
The contents of the block don't even make it to the ajax call, what gives?
EDIT:
I'll include my "content" block here:
in my template:
{% extends 'base.html' %}
{% block content %}
<div class="big-title text">Log in</div>
<div class="form-container">
<form name="login-form" id="user" method="post" action="/login/" enctype="multipart/form-data" class="text">
{% csrf_token %}
<div class="title">Enter your credentials</div>
<div class="form-row">
<div class="form-flex">
<div class="field-container">
<div class="field-input-container">
<div class="field-label accent">Username</div>
<div class="field-input">
<input class="field-input-element" type="text" name="username" />
</div>
</div>
<div class="field-help">Your username is always lowercase.</div>
</div>
</div>
<div class="form-flex">
<div class="field-container" style="height: 110px">
<div class="field-input-container">
<div class="field-label accent">Password</div>
<div class="field-input">
<input class="field-input-element" type="password" name="password" />
</div>
</div>
<div class="field-help"></div>
</div>
</div>
</div>
<div class="form-button-container">
<div class="form-error"></div>
<div class="form-message"></div>
<input type="submit" name="submit" value="Accept" class="button form-button"/>
</div>
</form>
</div>
{% endblock %}
In my base (base.html)
<body>
<div id="modal-container">
<div id="modal-overlay">
<div id="modal-items">
</div>
</div>
</div>
<div id="wrapper">
<header>
<div id="header-title" class="text accent">App name</div>
<div id="header-nav">
<nav>
{% if user.is_authenticated %}
Home
Feed {% if request.user.is_superuser %}
Admin {% endif %}
N
<a href="/{{ request.user }}" class="header-avatar-small-a">
<div class="text header-greeting">Hi, {{ user.userprofile.display_name }}</div>
<div class="header-avatar-small">
{% if not user.userprofile.avatar == '' %}
<img src="{{ MEDIA_URL }}users/{{ user }}/avatar" alt=""> {% else %}
<img src="{{ MEDIA_URL }}users/avatar" alt=""> {% endif %}
</div>
</a>
{% else %}
Log in
Create account {% endif %}
</nav>
</div>
<div class="progress">
<div id="header-progress" class="fill"></div>
</div>
</header>
<main>
{% block content %} {% endblock %}
</main>
<footer></footer>
</div>
</body>
</html>
Template source is the template actual HTML, not the file reference

Resources