I am trying to get all the post, posted in the same category. So my url looking like this, '..../category/Sports' where sports is a category. But if I enter this url, I got page, not found. I have also a html file called category. I also made makemigrations and migrate a several times
My views.py file:
from .models import Post, Category
..............
def CatView(request, cats):
posts = Post.objects.filter(category=cats)
return render(request,'category.html',{"cats":cats, 'posts':posts})
urls.py file:
from django.urls import path
from .views import *
urlpatterns = [
path('',HomeView.as_view(), name='home'),
path('article/<int:pk>', ArticleDetailView.as_view(), name='article_detail'),
path('add-post/', Addblogview.as_view(), name='add_post'),
path('add-category/', AddCategoryview.as_view(), name='add_category'),
path('article/edit/<int:pk>', UpdatethePost.as_view(), name='add_task'),
path('article/delete/<int:pk>', DeleteThePost.as_view(), name='delete_task'),
path('category/<int:cats>', CatView, name='category'),
]
If I change <str:cats> I ended up with ValueError Field 'id' expected a number but got 'Sports'
My models.py file:
from django.db import models
from django.contrib.auth.models import User
from django.urls import reverse
from datetime import datetime, date
class Category(models.Model):
name = models.CharField(max_length=255, default='uncategorized')
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('article_detail',args=str(self.id))
class Post(models.Model):
title = models.CharField(max_length=255)
title_tag=models.CharField(max_length=255)
author = models.ForeignKey(User,on_delete=models.CASCADE)
body = models.TextField()
post_date = models.DateField(auto_now_add= True)
category = models.ForeignKey(Category,on_delete=models.CASCADE)
def __str__(self):
return self.title + "|" + str(self.author)
def get_absolute_url(self):
return reverse('article_detail',args=str(self.id))
My category.html:
{{cats}}
You haven't set a primary key for Category, so the primary key becomes the numeric ID of the row, and the ForeignKey in Post needs to match that. You really want to set primary_key=True when you create the name field in Category.
Maybe you should just add a slash to the end of your URL in urls.py and try again? :)
Related
I have my API in Django REST Framework:
Here is my models.py:
class myModel(models.Model):
user_email = models.CharField(max_length= 200, null= False)
Here is my views.py:
class GetItemsByEmail(generics.ListAPIView):
def get_queryset(self):
email_items = self.request.query_params.get("user_email")
if(email_items is not None):
itemsReturned = myModel.objects.all().filter(user_email = email_items)
return Response(data= itemsReturned)
Here is my urls.py:
url_patterns = [
path('users/account=<str:id>/shipments', GetItemsByEmail.as_view()),
]
My Question:
I am getting an empty list, getting nothing from making an API call to the above endpoint.
I want to get all the items in the database associated with a particular email?
In your views.py:
from rest_framework import generics
from .models import * # noqa
from .serializers import *
class GetItemsByEmail(generics.ListAPIView):
queryset = MyModel.objects.all() # noqa
serializer_class = MyModelSerializer
def get_queryset(self):
if self.kwargs.get('user_email_pk'):
return self.queryset.filter(id=self.kwargs.get('user_email_pk'))
return self.queryset.all()
In models.py I had to create another model to have the result that you want (get all database by a specific user_email!):
from django.db import models
class MyModel(models.Model):
user_email = models.CharField(max_length=200, null=False)
def __str__(self):
return self.user_email
class ServicesModel(models.Model):
# Just an example to emulate the expected result, do not worry about it!
name = models.CharField('Name', max_length=200)
user_email_service = models.ForeignKey(MyModel, related_name='services', on_delete=models.CASCADE) # Just an example to emulate the expected result, do not worry about it!
def __str__(self):
return self.name
In serializers.py:
from rest_framework import serializers
from .models import MyModel, ServicesModel
class ServiceModelSerializer(serializers.ModelSerializer):
class Meta:
model = ServicesModel
fields = (
'name',
)
class MyModelSerializer(serializers.ModelSerializer):
services = ServiceModelSerializer(many=True, read_only=True)
class Meta:
model = MyModel
fields = (
'id',
'user_email',
'services',
)
In urls.py:
from django.urls import path
from core.views import GetItemsByEmail
urlpatterns = [
path('users/', GetItemsByEmail.as_view(), name='users'), # Ignore!
path('users/account=<str:user_email_pk>/shipments/', GetItemsByEmail.as_view(), name='user_email'),
]
In the test that I made localy I created two 'user_email' and each one have diferent 'services' so you are able to get all the data by the id, images of the result:
You obviously only need to get attention in 'views.py' and 'serializers.py', I just created all this code to get in the expected result!
If you want your query to be case insensitive, you can try the following:
myModel.objects.filter(user_email__iexact=email_items)
HI working on a new site using Django. can't seem to figure this bug out. First the intended site will be structured as;
Home page - Showing different languages with links to countries you can learn those languages in.
Click on a country on home page -> Country page
Country page will list all fo the schools that teach that language in that country.
Click on a school on country page -> School page.
I figured out this line of code in the Country page is causing the issue, but I don't know how to fix it
<a href="{% url 'schools' schools.id %}">
<div class="left"><h4>Test Link</h4></div>
</a>
This is the error I get in the browser
NoReverseMatch at /5/ Reverse for 'schools' with arguments '('',)' not found. 1 pattern(s) tried: ['(?P<country_id>[0-9]+)/(?P<schools_id>[0-9]+)/$']
Code from the project:
Models.py
from django.db import models
class Languages(models.Model):
language = models.CharField(max_length=100, blank=True, null=True)
country = models.ManyToManyField('Country', blank=True)
image = models.CharField(max_length=100, blank=True)
def __str__(self):
return self.language
class Country(models.Model):
country_name = models.CharField(max_length=50)
country_image = models.CharField(max_length=100, blank=True)
country_city = models.ManyToManyField('City', blank=True)
def __str__(self):
return self.country_name
class City(models.Model):
city_name = models.CharField(max_length=50)
city_image = models.CharField(max_length=1000, blank=True)
city_schools_in = models.ManyToManyField('Schools', blank=True)
def __str__(self):
return self.city_name
class Schools(models.Model):
school_name = models.CharField(max_length=100)
school_image = models.CharField(max_length=1000, blank=True)
school_country = models.ManyToManyField('Country', blank=True)
school_city = models.ManyToManyField('City', blank=True)
school_description = models.TextField()
school_accreditations = models.ManyToManyField('Accreditations', blank=True)
school_lpw = models.IntegerField()
school_cs = models.IntegerField()
school_course = models.ManyToManyField('CoursePrices', blank=True)
def __str__(self):
return self.school_name
class Accreditations(models.Model):
accreditation_name = models.CharField(max_length=50)
def __str__(self):
return self.accreditation_name
class CoursePrices(models.Model):
course_title = models.CharField(max_length=50, blank=True)
lessons_per_week = models.IntegerField()
class_size = models.IntegerField()
weekly_price = models.IntegerField()
language_level = models.CharField(max_length=50, blank=True)
def __str__(self):
return self.course_title
Views.py
from django.shortcuts import render
from django.http import Http404
from .models import Schools, CoursePrices, Languages, Country, City
def home(request):
languages = Languages.objects.all()
return render(request, 'home.html', {
'languages': languages,
})
def country(request, country_id):
try:
country = Country.objects.get(id=country_id)
except Languages.DoesNotExist:
raise Http404('Language not found')
return render(request, 'country.html', {
'country': country,
})
def schools(request, country_id, schools_id):
try:
schools = Schools.objects.get(id=schools_id)
except Schools.DoesNotExist:
raise Http404('school not found')
return render(request, 'schools.html', {
'schools': schools,
})
urls.py
from django.contrib import admin
from django.urls import path
from schools import views
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.home, name='home'),
path('<int:country_id>/', views.country, name='country'),
path('<int:country_id>/<int:schools_id>/', views.schools, name='schools'),
]
Project structure screenshot
Any help would be greatly appreciated. Also please forgive any mistakes in posting or coding, still very new to coding and stack overflow / life in general :)
Your path named schools requires two arguments, you only passed one, so it failed to match any route.
Your comment on Rafael's answer that it is still not matching the path, even with two arguments provided, is because of the order of the paths in your urls.py file.
Django will go through the list of paths in order, and because a path with the single parameter country_id is found first it tries that but fails because you have a second parameter.
To fix that change the order of your paths
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.home, name='home'),
# next two lines have been swapped.
path('<int:country_id>/<int:schools_id>/', views.schools, name='schools'),
path('<int:country_id>/', views.country, name='country'),
]
The 'schools' url needs two (2) arguments. You only pass one (1). In this case: schools.id
Django only finds a reverse match if you pass the correct amount of arguments. In this case, you should pass a country id AND a school id.
E.g. {% url 'schools' country_id=country.id schools_id=schools.id %} if you also have a country variable.
EDIT: '('',)' in your error message don't really look like integers. Are you sure the template variables exists and are integers?
this is my viewset:
class PollViewSet(viewsets.ReadOnlyModelViewSet):
queryset = Poll.objects.all()
serializer_class = PollSerializer()
def get_queryset(self):
country = self.kwargs.get('pk', None)
if country is not None:
django_countries.Countries.name(country)
return self.queryset.filter(personality__country__name=country)
else:
country = self.request.user.preferred_country
return self.queryset.filter(personality__country=country)
model.py :
from django_countries.fields import CountryField
class Personality(models.Model):
name = models.CharField(max_length=100)
bio = models.TextField()
age = models.IntegerField()
class Gender(models.TextChoices):
MALE = 'MALE', _('Male')
FEMALE = 'FEMALE', _('Female')
OTHER = 'OTHER', _('Other')
gender = models.CharField(
max_length=6,
choices=Gender.choices,
default=Gender.MALE,
)
country = CountryField(null=True)
picture = models.ImageField(upload_to='uploads/profile_images/%Y/%m/%d')
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name
class Poll(RulesModel):
personality = models.OneToOneField(Personality, related_name='polls', on_delete=models.CASCADE)
start_date = models.DateTimeField(null=True)
end_date = models.DateTimeField(null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return 'poll#' + str(self.id) + ' ' + self.personality.name
Urls.py
from django.conf.urls.static import static
from django.urls import path, include
from liderate import settings
from .views import PollViewSet, PersonalityViewSet, PollListViewSet
from rest_framework import routers
router = routers.DefaultRouter()
router.register(r'polls', PollViewSet)
router.register(r'polls-list', PollListViewSet)
router.register(r'personalities', PersonalityViewSet)
urlpatterns = [
path('', include(router.urls)),
]
here it raises exception that "Unsupported lookup 'name' for CountryField or join on the field not permitted."
this is raised in the if condition (else condition works perfectly fine). is there any other way of filtering the query set based on the country's name
i actually want to view only the polls related to country passed as a param in the get url
I had a field named location_countries in my project model based on CountryField. It was a multiselect and I needed to create a search based on country name or any other information available in project's other fields. conventional ways e.g "filter(fieldname__icontains) or Q(fieldname__country__name) etc failed. After a lot of trouble, search and thinking, I finally devised a workaround that is working as I intended. Now by giving any keywords for example "samo" in my search field it returns all projects based in "American Samoa" or "afghan" and it retruns all projects based in "Afghanistan". Hope This helps you also. Search field in normal html input tag named "searchTxt". to avoid duplication i first converted result to set and then back to list.
def viewProjects(request):
if request.user.is_authenticated:
if 'searchTxt' in request.GET:
qry = request.GET['searchTxt']
countries_list = []
pros = Project.objects.all()
for pro in pros:
for i in pro.location_countries:
if qry.lower() in i.name.lower():
countries_list.append(pro.project_heading)
res=Project.objects.filter(project_heading__in=countries_list)
projs = Project.objects.filter(
Q(project_id__icontains=qry)|
Q(project_heading__icontains=qry) |
Q(project_description__icontains=qry)|
Q(sla_type__icontains=qry)|
Q(project_type__icontains=qry)|
Q(project_priority__icontains=qry)|
Q(location_countries__exact=qry)|
Q(location_cities__icontains=qry)|
Q(project_manager__username__icontains=qry)|
Q(escalation_manager__username__icontains=qry)
)
project = list(chain(res, projs))
prj = set(project)
projects=list(prj)
context = { 'projects':projects }
return render(request, 'admin_view_projects.html', context)
else:
projects = Project.objects.all()
context = { 'projects':projects }
return render(request, 'admin_view_projects.html', context)
else:
return redirect('index')
This question already has answers here:
Hit counter for pages in Django
(3 answers)
Closed 3 years ago.
I have several articles, and when viewing them, it is necessary to calculate the number of these views for each article. And show how many views on the article
enter image description here
For example, I wanted to do this by clicking on the link so that it was added to "view = models.Integerfiels" 1
my models.py
from django.db import models
from taggit.managers import TaggableManager
class Articles(models.Model):
title = models.CharField(max_length= 200)
post = models.TextField()
date = models.DateTimeField()
img = models.ImageField(upload_to='', default="default_value")
tags = TaggableManager()
article_like = models.IntegerField(default='0')
article_dislike = models.IntegerField(default='0')
view = models.IntegerField(default='0')
font_size = models.IntegerField()
def __str__(self):
return self.title
views.py
class ArticleIndex(ListView):
model = Articles
template_name = 'news/posts.html'
class ArticleDetail(DetailView):
model = Articles
template_name = 'news/post.html'
urls.py
urlpatterns=[
path('', ArticleIndex.as_view(), name='articles_list'),
path('<int:pk>/', ArticleDetail.as_view(), name='article_detail'),
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
What i advise you to do here is to create your own view like that
from django.db.models import F
def ArticleDetailView(request, pk)
Articles.objects.filter(pk=pk).update(view=F('view') + 1)
article_details = Articles.objects.filter(pk=pk).first()
return render(request, 'the_path_to_your_detail_template.html', {'article_details': article_details})
In yout url.py you do like this :
path('your_url/<int:pk>/', views.ArticleDetailView, name='article_detail'),
In your forloop template where there all the article you just need to add the pk to the href of the anchor tag like this :
{{ article }}
i am new on django and i need your help, trying since many days to understand django-autocomplete-light, after setup my test,
http://192.168.0.108:8000/country-autocomplete/ work, data is showed like explaned here http://django-autocomplete-light.readthedocs.io/en/master/tutorial.html#overview
But after following next step, i am getting error:
AttributeError at /auto
'list' object has no attribute 'queryset'
Request Method: GET
Request URL: http://192.168.0.108:8000/auto
Django Version: 1.10.3
Exception Type: AttributeError
Exception Value:'list' object has no attribute 'queryset'
Exception Location: /home/alcall/ENV/lib/python3.4/site-packages/dal/widgets.py in filter_choices_to_render, line 161
Below my setup:
urls:
from dal import autocomplete
from django.conf.urls import url
from django.contrib import admin
from rates.view.index import *
from rates.view.index import UpdateView
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(
r'^country-autocomplete/$',
CountryAutocomplete.as_view(),
name='country-autocomplete',
),
url(r'^auto$',
UpdateView.as_view(),
name='select',
),
]
models.py
from __future__ import unicode_literals
from django.db import models
class Country(models.Model):
enabled = models.IntegerField()
code3l = models.CharField(unique=True, max_length=3)
code2l = models.CharField(unique=True, max_length=2)
name = models.CharField(unique=True, max_length=64)
name_official = models.CharField(max_length=128, blank=True, null=True)
prix = models.FloatField()
flag_32 = models.CharField(max_length=255, blank=True, null=True)
flag_128 = models.CharField(max_length=255, blank=True, null=True)
latitude = models.DecimalField(max_digits=10, decimal_places=8, blank=True,$
longitude = models.DecimalField(max_digits=11, decimal_places=8, blank=True$
zoom = models.IntegerField(blank=True, null=True)
class Meta:
managed = False
db_table = 'country'
def __str__(self):
return self.name
view (include form too)
from dal import autocomplete
from django.shortcuts import render
from rates.models import Country
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.http import HttpResponse
from django import forms
from django.core.urlresolvers import reverse_lazy
from django.views import generic
class CountryAutocomplete(autocomplete.Select2QuerySetView):
def get_queryset(self):
# Don't forget to filter out results depending on the visitor !
# if not self.request.user.is_authenticated():
# return Country.objects.none()
qs = Country.objects.all()
if self.q:
qs = qs.filter(name__istartswith=self.q)
return qs
class Form_country(forms.ModelForm):
class Meta:
model = Country
fields = ('name', 'code2l')
widgets = {
'name': autocomplete.ModelSelect2Multiple(
'country-autocomplete'
)
}
class UpdateView(generic.UpdateView):
model = Country
form_class = Form_country
template_name = 'fr/public/monformulaire.html'
success_url = reverse_lazy('select')
def get_object(self):
return Country.objects.first()
I had the same issue. The problem here is with the widget. Tried to fix it for very long. The only way in worked for me was changing form's widget.
If it doesn't matter that much you can use autocomplete.ListSelect2 instead, it worked for me.
So try this:
class Form_country(forms.ModelForm):
class Meta:
model = Country
fields = ('name', 'code2l')
widgets = {
'name': autocomplete.ListSelect2(
'country-autocomplete'
)
}
Actually you can just try any other autocomplete widget and see weather it works
I you create the widget in __init__(), then this work-around of issue #790 helps:
form.fields['name'].widget.choices = form.fields['name'].choices
Here is my implementation, where I used it to suggest similar names that are already present in a model
IMPORTANT: After you must have done all these, don't forget to run python manage.py collectstatic.
Also note that you wish to include a placeholder in your form field you have to do it with data-placeholder in the widget autocomplete widget.
When you run it, you'll see this message
Found another file with the destination path
'admin/js/jquery.init.js'. It will be ignored since only the first
encountered file is collected. If this is not what you want, make sure
every static file has a unique path.
This is the reason the documentation states here that you must place dal and dal_select2 before django.contrib.admin in your INSTALLED_APPS
models.py
from django.db import models
class Patient(models.Model):
name = models.CharField(max_length=100)
stable = models.BooleanField(default=False)
views.py
from django.db.models import Q
from dal import autocomplete
class NewName(autocomplete.Select2QuerySetView):
"""Suggest similar names in form"""
def get_queryset(self):
qs = People.objects.filter(stable=True)
if self.q:
query = Q(name__contains=self.q.title()) | Q(name__contains=self.q.lower()) | Q(name__contains=self.q.upper())
qs = qs.filter(query)
return qs
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('new-name/', views.NewName.as_view(), name='new_name_autocomplete'),
]
forms.py
class PatientForm(forms.ModelForm):
class Meta:
model = Patient
fields = ["stable", "name"]
widgets = {
"name" : autocomplete.ModelSelect2(url=reverse_lazy('new_name_autocomplete'), attrs={'class' : 'form-control', 'data-placeholder' : "Name"}),
I had to modify dal/widgets.py and comment out the queryset filtering as shown below. It seems to be a bug or something. The issue has been raised here. But if you're using
autocomplete.ListSelect2() as your widget, then there's no need for that.
class QuerySetSelectMixin(WidgetMixin):
"""QuerySet support for choices."""
def filter_choices_to_render(self, selected_choices):
"""Filter out un-selected choices if choices is a QuerySet."""
# self.choices.queryset = self.choices.queryset.filter(
# pk__in=[c for c in selected_choices if c]
# )