Navbar For Ecommerce Website Using Django - django

I am designing eCommerce website based on django in backend. I want to create navbar which will contain menu based on categories of products.
I want this Navbar dynamic as whenever new category posted it should automatically appear in menu field. My front end is bootstrap and Html.
Please help me with logic.
Thank You.

this is very general by I try to give you some clue to search forward.
first, think of a navbar something like this:
<nav class="navbar">
product1
product2
.
.
.
</nav>
you can see a pure sub navbar example in this link or you can use bootstrap if you want.
now let's go back to Django templates, you must have something like base.html template file that your navbar code is there and every other template will inherit the navbar from it, then in your views.py for every view just pass the categories that you have already queried from the database to render function:
def view(request):
categories = Category.objects.all()
.
.
.
return render(request, 'some.html',
{
'categories': categories,
.
.
.
}
this will pass all the categories in your database to the base.html template where you can just put it in a {% for %} template tag to inject to HTML:
<nav class="navbar">
{% for catg in categories %}
{{ catg.name }}
{% endfor %}
</nav>
ok, this is not the definite solution, but I think you got the algorithm.

Use bootstrap.it will help you for mobile friendliness.they have a ready made nice navbar for use that you can modify.just download bootstrap examples,get the code for navbar.
design your main/home page as you like.then to stick the nav to other pages,use block content like this:
{% block content %}
code...
code...
{% endblock %}
there are lots of tutorials for extending base html page.pick and watch 'em.

in views.py
def your_view_function(request):
categories = Category.objects.all()
return render(request,'your_template.html',{'categories':categories})
in template
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Categories
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
{% for category in categories %}
<a class="dropdown-item" href="#">{{category.name}}</a>
{% endfor %}
</div>
</li>
</div>
</nav>

Thank You All For Your Answers. I have created dynamic navbar as follows
First I created context_processor.py file in which I imported ProductModel as follows:
I added above file in settings.py
from products.models import ProductModel
def context_prod(request):
allCat=[]
catProd = ProductModel.objects.values("category","id")
cats = {item["category"] for item in catProd}
for cat in cats:
prod = ProductModel.objects.filter(category=cat)
subcat = prod.values("subcategory","id")
subcat = {item["subcategory"] for item in subcat}
allCat.append([prod, subcat])
context={
"allCat": allCat
}
return(context)
Then in navbar.html I added following HTML code
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
{% for prod, subcat in allCat %}
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
{{ prod.0.category }}
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
{% for i in subcat %}
<a class="dropdown-item" href="#">{{ i }}</a>
{% endfor %}
</div>
</li>
{% endfor %}
And Bingo..!! It worked

Related

Django 2.2 error - Integrity Error, NOT NULL constraint failed

I have a sample Django 2.2 project that has a search bar in the top right corner of the nav bar (taken from the Bootstrapers):
navbar.html:
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="/">Navbar</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="/">Home <span class="sr-only">(current)</span></a>
</li>
{% if user.is_authenticated %}
<li class="nav-item">
<a class="nav-link" href="/search/">Search</a>
</li>
...
{% endif %}
<li class="nav-item">
<a class="nav-link" href="/a/">A</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/b/">B</a>
</li>
</ul>
<form class="form-inline my-2 my-lg-0" action = '/search/'>
<input class="form-control mr-sm-2" type="search" name="q" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
</div>
</nav>
It returns "You searched for [search argument]" to the url '/search/' and works fine. I would like to bring it from the nav bar under the 'Search' menu in the nav bar. I have the following:
searches/models.py
from django.db import models
from django.conf import settings
# Create your models here.
class SearchQuery(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, blank = True, null=True, on_delete=models.SET_NULL)
query = models.CharField(max_length=220)
timestamp = models.DateTimeField(auto_now_add=True)
searches/views.py:
from django.shortcuts import render
from django.contrib.auth.decorators import login_required
from django.contrib.admin.views.decorators import staff_member_required
from .models import SearchQuery
# Create your views here.
#login_required
# staff_member_required
def search_view(request):
query = request.GET.get('q', None)
user = None
if request.user.is_authenticated:
user = request.user
SearchQuery.objects.create(user=user, query=query)
context = {"query": query}
return render(request, 'searches/view.html',context)
searches/templates/searches/view.html:
{% extends "base.html" %}
{% block content %}
{% if user.is_authenticated %}
<form action = '/search/'>
<input type="search" name="q" aria-label="Search">
<button type="submit">Search</button>
</form>
<div class='row'>
<div class='col-12 col-8 mx-auto'>
<p class='lead'>You searched for {{ query }}</p>
</div>
</div>
{% endif %}
{% endblock %}
When I search from the search bar in the navigational pane, it returns the argument. But when I want to run the search from the search bar and click on the Search tab, I get this:
IntegrityError at /search/
NOT NULL constraint failed: searches_searchquery.query
...
...searches\views.py in search_view
SearchQuery.objects.create(user=user, query=query)
Why am I getting this ?
EDIT:
After making this change in searches/views.py:
query = request.POST.get('q', None)
I get this error in the runtime:
django.db.utils.IntegrityError: NOT NULL constraint failed: searches_searchquery.query
and in the browser:

Django template sidebar not rendering as it should

In a Django project, I have a side bar that is not rendering in the correct place. Instead of coming up on the right hand side of the content, as it does for the other pages that have similar content, the side bar in this case is at the very bottom. I cannot figure out how to move it, and have tried various things in the base.html and moving around the Django templating language block content.
Rendering the template (register.html) looks like this:
It should however look like this, as per the tutorial:
Relevant part of the base.html
<!--this is django templating language-->
<link rel="stylesheet" href="{% static 'worldguestbook\main2.css' %}"/>
</head>
<body>
<header class="site-header">
<nav class="navbar navbar-expand-md navbar-dark bg-steel fixed-top">
<div class="container">
<a class="navbar-brand mr-4" href="/">FakeBook Newsfeed</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarToggle" aria-controls="navbarToggle" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarToggle">
<div class="navbar-nav mr-auto">
<a class="nav-item nav-link" href="{% url 'socialmedia-home' %}">Home</a>
<a class="nav-item nav-link" href="{% url 'socialmedia-about' %}">About</a>
</div>
<!-- Navbar Right Side -->
<div class="navbar-nav">
<a class="nav-item nav-link" href="{% url 'socialmedia-login' %}">Login</a>
<a class="nav-item nav-link" href="#">Register</a>
</div>
</div>
</div>
</nav>
</header>
register.html
{% extends "socialmedia/base.html" %}
{% block content %}
<div class="content-section">
<form method="POST">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Hello: Register today!</legend>
{{form.as_p}}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Register</button>
</form>
<div class="border-top pt-3">
<small class="text-muted">Signed up already? <a class="ml-2" href="#">Login</a> here</small>
</div>
{% endblock content %}
views.py
#USERS (register) view.py
from django.shortcuts import render
from django.contrib.auth.forms import UserCreationForm
# Create your views here.
def register(request):
form = UserCreationForm()
return render(request, 'users/register.html',{'form':form})
Please note that the main2.css style sheet is referenced in the base.html and works fine on all the other pages except for this one. In the other pages the side bar renders correctly on the right hand side of the page.
The problem was a missing div, that compeltely escaped my attention.
The register.html page can be re-written as the below. Note the divs, one of which was missing. I also sorted out the indentation which helps.
{% extends "socialmedia/base.html" %}
{% block content %}
<div class="content-section">
<form method="POST">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Hello: Register today!</legend>
{{form.as_p}}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Register</button>
</div>
</form>
<div class="border-top pt-3">
<small class="text-muted">
Signed up already? <a class="ml-2" href="#">Login</a>
</small>
</div>
</div>
{% endblock content %}

Py 3.6 // Django 2.1.4 : Accessing User Profile mysteriously changes the status of user.is_authenticated to True

I have been having this problem for 2 weeks now I can't seem to solve it.
I have a social website where user's can upload their resumes for recruiters to see.
And when I access some user's profile, the Navbar acts as if I am logged in, which I am not.
I tried fixing this issue by using get_queryset() ,it worked but I couldn't manage to display user's profile data.
so I stuck with get().
Here's a visual explanation:
As you can see the navbar says Home/Login/Signin
Now if I access John Doe's Profile, the navbar will switch to Home/Profile/Logout:
Here's my code;
views.py:
class HomeProfile(ListView):
"Di splays all active users in db"
template_name = 'profile/home_profile.html'
queryset = MyModel.objects.filter(is_active=True)
class Get_Profile(DetailView):
"fetches user's profile"
def get(self, request, pk):
user = MyModel.objects.get(pk=pk)
return render(request, 'profile/profile.html', {'user':user})
urls.py
urlpatterns = [
path('homepage/profiles/', user_view.HomeProfile.as_view(), name='homepage'),
path('homepage/profile/<int:pk>/', user_view.Get_Profile.as_view(), name='user-profile'),
]
base_test.html
<nav class="navbar navbar-expand-sm navbar-dark bg-dark sticky-top">
<a class="navbar-brand" href="{% url 'home' %}">Navbar</a>
<button class="navbar-toggler d-lg-none" type="button" data-toggle="collapse" data-target="#collapsibleNavId" aria-controls="collapsibleNavId"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="collapsibleNavId">
<ul class="navbar-nav ml-auto mt-2 mt-lg-0">
<li class="nav-item active">
<a class="nav-link" href="{% url 'homepage' %}">Home<span class="sr-only">(current)</span></a>
</li>
{% if not user.is_authenticated %}
<li class="nav-item">
<a class="nav-link" href="{% url 'login' %}">Log In</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'signup' %}">Sign Up</a>
</li>
{% else %}
<li class="nav-item">
<a class="nav-link" href="#">Profile</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'logout' %}">Log Out</a>
</li>
{% endif %}
</ul>
</div>
</nav>
home_profile.html
<!-- this is the home template that displays all active users -->
{% extends 'base_test.html' %}
{% block title %} My Site | Profiles {% endblock title %}
{% block content %}
<div class="card-columns text-center padding">
{% for user in mymodel_list %}
<div class="card">
<img class="rounded-circle" src="{{user.profile.image.url}}" width=150 height=150>
<div class="card-body">
<h5 class="card-title">Full name : {{user.get_full_name}}</h5>
<p class="crad-text">Occupation/job : {{user.profile.occupation}}</p>
<a type="button" href="{% url 'user-profile' user.pk %}" style="color:whitesmoke;" class="btn btn-primary btn-sm">Profile</a>
</div>
</div>
{% endfor %}
</div>
{% endblock content %}
{% block footer %}
{% endblock footer %}
profile.html
<!-- user profile template -->
{% extends 'base_test.html' %}
{% load custom_tags %}
{% block title %} My Site | {{user.get_full_name}} {% endblock title %}
{% block content %}
<div class="container">
<div class="row">
<div class="col-lg-8 order-lg-2 padding">
<div class="tab-content">
<div class="tab-pane active" id="profile">
<div class="row">
<div class="col-lg-12">
<h6><strong>About</strong></h6>
<p>
{{user.profile.bio}}
</p>
<hr>
</div>
<div class="col-lg-12">
<h6><strong>Skills</strong></h6>
{% for skill in user.profile.skills|split:',' %}
<span class="badge badge-primary">{{skill}}</span>
{% endfor %}
<hr>
<h6><strong>Hobbies</strong></h6>
<p>
{% for hobbie in user.profile.hobbies|split:',' %}
<span class="badge badge-success">{{hobbie}}</span>
{% endfor %}
</p>
<hr>
</div>
<!-- removes the social part -->
</div>
</div>
</div>
</div>
<div class="col-lg-4 order-lg-1 padding">
<h1 class="mb-3 text-center">{{user.get_full_name}}</h1>
<hr>
<img src="{{user.profile.image.url}}" class="mx-auto img-fluid rounded-circle d-block" alt="avatar" width=150><br>
<div class="text-center">
<h4>{{user.profile.school}}</h4>
<p><strong>Hometown :</strong> {{ user.profile.hometown}}</p>
<p><strong>Current City:</strong> {{user.profile.location}}<p>
<p><strong>Occupation/Job:</strong> {{user.profile.occupation}}<p><br>
<hr>
<button type="button" class="btn btn-outline-success btn-md">View CV</button>
</div>
</div>
</div>
</div>
{% endblock content %}
{% block footer %}
{% endblock footer %}
I don't know What is causing this strange behaviour!!
Actually, you are mixing up with request.user and your user object for resume. You should change the context variable name from user to something else. for example:
class Get_Profile(DetailView):
"fetches user's profile"
def get(self, request, pk):
user = MyModel.objects.get(pk=pk)
return render(request, 'profile/profile.html', {'profile':user}) # <-- Here
You've used the same variable name, user, for the user whose profile you are viewing as for the one who is actually using the site. You need to pick another name.
(Also, unrelated, but you don't need to - and shouldn't - define the get method in your detail view.)

Unable to access html page

Hello i dont know what the problem.. why when i click on button about us i am not able to be in the new page, but the url in the website change. The page reads only the extended block but the new one no.
this is the template (only the one related to the buttons)
<div class="btn-group cust-dropdown pull-right">
<button type="button" class="btn btn-default dropdown-toggle cust-dropdown" data-toggle="dropdown"role="button">
<i class="glyphicon glyphicon-menu-hamburger"></i>
</button>
<ul class="dropdown-menu" role="menu">
<li>About</li>
<li>Documentation</li>
<li>Pricing</li>
<li>Contact us</li>
<li>Register</li>
</ul>
</div>
This is the view:
def base(request):
return render(request, 'base.html', {'active_page':'base'})
def about(request):
return render(request, 'about.html', {'active_page':'about'})
And the about html:
{% extends 'base.html' %}
{% block title %}About{% endblock %}
{% block content %}
<div class='row'>
<div class="col-lg-6">
<h3>Summary</h3>
<p> Our organization is related to </p>
</div>
</div>
{% endblock %}
The image link is here, only the extendable form appear when i click on about

Make clicked tab active in Bootstrap

I am using Django and integrated Bootstrap with Django. Here is my HTML code for the navigation bar:
<div class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Project name</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="active">Home</li>
<li >About</li>
<li>Contact</li>
<li class="dropdown">
Games <span class="caret"></span>
<ul class="dropdown-menu" role="menu">
<li>RacingDNA</li>
<li>Skater Game</li>
</ul>
</li>
</ul>
</div><!--/.nav-collapse -->
</div>
</div>
I have written the CSS for an active navigation bar also. Here, only one navigation bar is active. I want to make the clicked navigation bar active and thus apply my CSS. My CSS is working perfect for active navigation bar and for this situation only for one.
I googled and found a solution to add this jQuery:
$('.nav.navbar-nav > li').on('click', function (e) {
e.preventDefault();
$('.nav.navbar-nav > li').removeClass('active');
$(this).addClass('active');
});
Now here is where I am stuck. I don't know where to write this jQuery.
I put this file in the static/js folder and named this code nav-bar.js. However, there is no improvement. Where am I going wrong and where am I making mistakes?
If you dont want to send any additional context from views then you can handle it like this with resolver_match:
<li {% if request.resolver_match.url_name == 'home' %}class="active"{% endif %}>
HOME
</li>
where 'home' is the name given to your url pattern for / (probably '^$') in your urls.py.
So obviously to use this you need to name all your url patterns, which is a good practice anyway.
This solution didn't work when the href attribute of your links will be different from href="#". Why ? Simply because each click on a link triggers a request to the server. In your JS code, you add the method preventDefault() in order to avoid this basic behavior, but I think that not really your objective for this purpose, isn't it ?
To handle this kind of feature you can update your template code by adding something like this :
base.html
<div class="collapse navbar-collapse" id="tn-navbar-collapse">
<ul class="nav navbar-nav">
<li class="{% if nbar == 'home' %}active{% endif %}">
HOME
</li>
...
</ul>
</div>
views.py
def your_view(request):
...
return render(request, 'yourtemplate.html', {'nbar': 'home'})
With this way, you don't have to manage this feature with javascript.
Alternative including URL namespaces:
<li class="nav-item {% if request.resolver_match.view_name == 'scores:list' %}active{% endif %}">
<a class="nav-link" href="{% url 'scores:list' %}">Scores</a>
</li>
I recently ran into this problem and tried every solution I could find. Eventually, I came to this. This example assumes the path to this content is yoursite.com/about
Give your link an id.
<li><a id="about" href="#">About</a></li>
var path = $(location).attr('pathname')
var pa = path.split("/")
$('#'+pa[1]).tab('show')
#rphonika has give a nice answer. But if you have many navigation menus then adding template logic in each list item makes the code untidy. Menu items can be assigned a unique id, the id passed in views and active class can be assigned using a one liner javascript code in html itself.
base.html
<ul class="nav navbar-nav navbar-left">
<li><a class="navmenu-a" id="overview" href="{% url 'webapp:overview' %}">Overview</a></li>
<li><a class="navmenu-a" id="plot" href="{% url 'webapp:plot' %}">Plot</a></li>
<li><a class="navmenu-a" id="board" href="{% url 'webapp:board' %}">Board</a></li>
<li><a class="navmenu-a" id="storyboard" href="{% url 'webapp:storyboard' %}">Storyboard</a></li>
<li><a class="navmenu-a" id="freqs" href="{% url 'webapp:freqs' %}">Faq</a></li>
</ul>
.
.
.
<script type="text/javascript">
{% if nmenu %} $("a#{{nmenu}}").addClass("navmenu-a-active") {% endif %}
</script>
views.py
def overview(request):
...
return render(request, 'overview.html', {'nmenu': 'overview'})
def plot(request):
...
return render(request, 'plot.html', {'nmenu': 'plot'})
And so on for other views
I think the easiest solution is JavaScript / CSS:
Anyway, here is the solution using Jquery. Notice n1,n2 classes in html
In base.html
<nav>
<ul class="nav flex-column">
<li class="nav-item">
<a class="nav-link n1" href="{% url 'polls:dashboard' %}">
<span data-feather="home"></span>
Dashboard
</a>
</li>
<li class="nav-item">
<a class="nav-link n2" href="{% url 'polls:restaurants' %}">
<span data-feather="file"></span>
Restaurants
</a>
</li>
</ul>
</nav>
<script>
$('nav').find('{% block active_link%}{%endblock%}').addClass('active')
</script>
Then in your dashboard template:
{% block active_link %}.n1{%endblock%}
In your restaurants template:
{% block active_link %}.n2{%endblock%}
After adding gamer's JavaScript into your template code_here , you got to make sure you have the similar settings in your CSS file also, in order to make JavaScript work.
.navbar-nav > li.active > a {
color: #d74b4b;
background: transparent;
border-bottom: none;
}
I would rather prefer to only edit the template using rather than editing both views and templates for this. People needing the same, rather than following the accepted answer, may consider the below way:
<ul class="navbar-nav">
<li class="nav-item {% ifequal request.path '/' %} active {% endifequal %}">
<a class="nav-link" href="/">Home</a>
</li>
</ul
You can change 'index' above with your own
You can check if a string is in your URL path. This is helpful for hierarchical or nested URL paths
<li {% if 'home' in request.get_full_path %}class="active"{% endif %}>
HOME
</li>
If you want activate by context you can do like this variable == to context in .views
<li class="nav-item {% ifequal variable context %}active{% endifequal%}">
<a class="nav-link" href="{% url 'scores:list' %}">Scores</a>
</li>