Django Tables adding a LinkColumn / NoReverseMatch Error - python

I have a model with some fields and I want to add a LinkColumn to a detail page. I have a working version, but I want to move to django-tables2
The problem is that the link column doesnt show any link, just a "-"
The model
class Events(models.Model):
id = models.IntegerField(primary_key=True)
date = models.DateField(null=True, blank=True)
time = models.TimeField(null=True, blank=True)
The Table. Here I tried with args=[A('id')] and args=[A('pk')]
class EventsTable(tables.Table):
time = tables.TemplateColumn("{{value|time:'H:i'}}", verbose_name='Time UTC')
detail_link = tables.LinkColumn('detail', args=[A('id')], verbose_name='Detail')
class Meta:
model = Events
attrs = {"class": "paleblue"}
fields = ("date", "time", "detail_link")
mi url pattern is
urlpatterns = patterns('',
url(r'^$', views.index, name='index'),
url(r'^(?P<event_id>\d+)/$', views.detail, name='detail'),
)
and the view
def index(request):
table = EventsTable(Events.objects.all(), order_by=('-date', '-time'))
RequestConfig(request, paginate={"per_page": PAGE_LIMIT}).configure(table)
return render(request, "db_interface/events.html", {"table": table})
EDIT:
Changing the detail_link to
detail_link = tables.LinkColumn('detail', args=[A('id')], verbose_name='Detail', empty_values=())
now I got a NoReverseMatch Exception
Reverse for 'detail' with arguments '(5075,)' and keyword arguments '{}' not found
the number 5075 is the id of the first event. I dont know if for any reason is not passing the argument as an int ?

Try:
detail_link = tables.LinkColumn('detail', args=[A('id')], verbose_name='Detail', empty_values=())
According to the docs, render methods are only called if the value for a cell is determined to be not an empty value. Since the Event model does not have a detail_link field, there's no value given to it.

Related

django app.models.VideoLibrary.DoesNotExist: VideoLibrary matching query does not exist

The problem is I can't type http://localhost:8000/1 to see spesific ViedoLibrary in my database. Can anyone help me to find the solution?
urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.index, name='index'),
path('main/', views.main, name='main'),
path('create_view/', views.create_view, name='create_view'),
path('list_view/', views.list_view, name='list_view'),
path('<id>', views.detail_view),
]
views.py
def detail_view(request, id):
context = {}
context['data'] = VideoLibrary.objects.get(shop_id=id)
return render(request, 'app/detail_view.html', context)
models.py
class VideoLibrary(models.Model):
shop_id = models.AutoField(primary_key=True, unique=True)
shop_name = models.CharField(max_length=264)
adress = models.TextField(max_length=264, default='')
Also if I type id=id in views.py the next error pops up : Cannot resolve keyword 'id' into field. Choices are: adress, attendance, equipment, films, genre, income, shop_id, shop_name, staff.
This are all my classes in models.py but there are also adress, shop_id and shop_name that are from specific model
Updated.
You have overriden the id field of your model that is why it won't work with id=id since the latter is actually shop_id. Change it accordingly and it should work.
The id error is telling you that you cannot use id as a field and giving you the list of available model fields you can use for filtering. See this answer for more details. Error: Cannot resolve keyword 'id' into field
Update 2
Your views:
from . models import VideoLibrary
def videoLibrary(request):
context = {}
context['data'] = VideoLibrary.objects.all()
return render(request, 'appname/list_view.html', context)
def detail_view(request, id):
context = {}
context['data'] = VideoLibrary.objects.get(shop_id=id)
return render(request, 'appname/detail_view.html', context)
Your urls.py:
urlpatterns = [
path('admin/', admin.site.urls),
path('videos/', views.videoLibrary, name='list_view'),
path('videos/<int:id>', views.detail_view),
]
Now, if you enter http://127.0.0.1:8000/videos this gives you the list view. And http://127.0.0.1:8000/videos/1 gives you VideoLibrary with id 1.

how to use StreamingHttpResponse in django rest framework?

i have a simple django rest framework and i want to know how can use StreamingHttpResponse in my project.
my model is like this:
class Article(models.Model):
user = models.CharField(max_length=100)
title = models.CharField(max_length=200)
description = models.TextField()
date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
and serializer for this model is like this:
class ArticleSerializers(serializers.ModelSerializer):
class Meta:
model = Article
fields = ['id', 'user', 'title', 'description', 'date']
i think my problem is in mu view or url. so i wrote code in view like this:
class StreamPost(viewsets.ModelViewSet):
queryset = Article.objects.all()
serializer_class = ArticleSerializers
def get_queryset(self):
stream = event_stream()
response = StreamingHttpResponse(stream, status=200, content_type='text/event-stream')
response['Cache-Control'] = 'no-cache'
return response
that the event_stream is like this:
def event_stream():
initial_data = ''
while True:
list_article = list(Article.objects.all())
data = json.dumps(list_article, cls=DjangoJSONEncoder)
if not initial_data == data:
yield "\ndata: {}\n\n".format(data)
initial_data = data
time.sleep(1)
the url is like this:
router = DefaultRouter()
router.register('stream', StreamPost, basename='stream')
urlpatterns = [
path('', include(router.urls)),
]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
i can't track the error and so i don't know where is my problem but when run my project with this codes the problem is like this:
Object of type Article is not JSON serializable
when i change the event_stream function the error changed like this:
def event_stream():
initial_data = ''
while True:
list_article = list(Article.objects.all().values('id', 'user', 'title', 'description', 'date'))
data = json.dumps(list_article, cls=DjangoJSONEncoder)
if not initial_data == data:
yield "\ndata: {}\n\n".format(data)
initial_data = data
time.sleep(1)
the error:
Got AttributeError when attempting to get a value for field `user` on serializer `ArticleSerializers`.
The serializer field might be named incorrectly and not match any attribute or key on the `bytes` instance.
Original exception text was: 'bytes' object has no attribute 'user'.

Why am I getting a No Reverse Match Error

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?

Django: How can I access and display details about the single "child" in the one-to-many relationship?

I have two models - the Company and Department. The Company can have many Departments - this is all connected with Foreign Key and works as expected. I have URLs and templates/views nicely setup and I can add the Company and then I can add Depratments to it. I am also able to access and create new Departments and assign them to the Company.
To see, say 5 last companies and last 5 Departments I have in the system I use this:
class IndexView(generic.ListView):
model = Company
template_name = 'company/index.html'
context_object_name = 'latest_company_list'
def get_queryset(self):
"""Return the last five created companies."""
return Company.objects.order_by('company_name')[:5]
class DeptIndexView(generic.ListView):
model = Department
template_name = 'department/index.html'
context_object_name = 'latest_department_list'
def get_queryset(self):
"""Return the last five created companies."""
return Department.objects.order_by('dept_name')[:5]
And here are the models from models.py
class Company(models.Model):
company_name = models.CharField(max_length=200)
company_dba = models.CharField(max_length=200)
class Meta:
verbose_name_plural = "companies"
def __str__(self):
return self.company_name
# on submit click on the company entry page, it redirects to the url below.
def get_absolute_url(self):
return reverse('company:index')
class Department(models.Model):
company = models.ForeignKey(Company, on_delete=models.CASCADE)
dept_name = models.CharField(max_length=200)
dept_code = models.IntegerField(default=0)
def __str__(self):
return self.dept_name
# on submit click on the department entry page, it redirects to the url below.
def get_absolute_url(self):
return reverse('company:index')
My urls.py file looks like this
app_name = 'company'
urlpatterns = [
# Company management views
path('', views.IndexView.as_view(), name='index'),
path('<int:pk>/', views.DetailView.as_view(), name='detail'),
path('add/', views.CompanyEntry.as_view(), name='add'),
path('update/<int:pk>/', views.CompanyUpdate.as_view(), name='update'),
path('delete/<int:pk>/', views.CompanyDelete.as_view(), name='delete'),
#Department management views
path('<int:pk>/department/', views.DeptIndexView.as_view(), name='dept_index'),
path('<int:pk>/department/add/', views.DeptEntry.as_view(), name='dept_add'),
path('<int:pk>/department/<int:fk>/', views.DeptDetailView, name='dept_detail'),
]
The issue here is that I don't know how to configure URL/path so that I can access details about one single Department.
I am trying to get something like http://127.0.0.1:8000/company/1/department/2/ where 2 is the id of the Department model.
And that last line in the code above doesn't seem to be working.
Instead, I am getting this as an error:
TypeError at /company/1/department/2/
init() takes 1 positional argument but 2 were given
Request Method: GET
Request URL: http://127.0.0.1:8000/company/1/department/2/
Django Version: 2.2.4
Exception Type: TypeError
Exception Value:
init() takes 1 positional argument but 2 were given
Exception Location: /Users/ABC/DjangoHR/lib/python3.7/site-packages/django/core/handlers/base.py in _get_response, line 113
I figured it out - I missed .as_view()
path('<int:pk>/department/<int:fk>/', views.DeptDetailView.as_view(), name='dept_detail'),
Thank you all for help and comments!

Django: URL pattern to include values from multiple fields

I'm fairly new to python and I'm trying to build a URL pattern that takes two fields as parameters. This is part of my model:
CATEGORY_CHOICES = (
('M', 'Music'),
('G', 'Games'),
('T', 'TV'),
('F', 'Film'),
('O', 'Misc'),
)
category = models.CharField(max_length = 1, choices = CATEGORY_CHOICES)
slug = models.SlugField(unique=True, max_length=255)
What I want to achieve is to be able to call a such as: thisblog.com/music/this-post where /music is the category and /this-post is the slug.
I had an attempt but I can't figure out how to do it properly:
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^$', 'blog.views.index'),
url(r'^(?P<category>[\w\-]+)/(?P<slug>[\w\-]+)/$', blog_post, name = 'blog_post'),
)
This gives me a 'NoReverseMatch at /' error.
Any help is greatly appreciated :)
UPDATE:
In my html template I have a link:
<p><a class="btn btn-default" href="{{post.get_absolute_url}}" role="button">Read more ยป</a></p>
get_absolute_url is defined as:
def get_absolute_url(self):
return reverse ('blog.views.post', args = [self.slug])
You have two errors in your get_absolute_url method. Firstly, you need to use the URL's name attribute since you have defined it. And secondly, you need to provide both parameters: category as well as slug.
So it should be:
return reverse('blog_post', args=[self.category, self.slug])
If you are using class based views then something like this would work:
# views.py
class ViewPost(DetailView):
model = Post # change this to the model
def get_queryset(self):
queryset = super(ViewQuizListByCategory, self).get_queryset()
return queryset.filter(category=self.kwargs['category'])
# urls.py
from .views import ViewPost
...
url(r'^(?P<category>[\w\-]+)/(?P<slug>[\w\-]+)/$',
ViewPost.as_view(),
name='blog_post'),
...
The template will be post_detail.html and would be placed as <project_root>/post/templates/post/post_detail.html

Categories