Error with url reverse() in function get_absolute_url()
can't reverse the url in every models (serial_slug) but url himself is exists!
this is main url.py
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^series/', include("serials.urls", namespace='series')),
url(r'^', include("serials.urls", namespace='homeview')),
]
this is my urls.py in my app
from django.conf.urls import include, url
from .views import homeview, post_of_serial, post_of_season, post_of_serie
urlpatterns = [
url(r'^$', homeview, name='homeview'), # /series/
url(r'^(?P<serial_slug>[\w-]+)/$', post_of_serial, name='post_of_serial'), # /series/Prison_Break/
url(r'^(?P<serial_slug>[\w-]+)/(?P<season_slug>[\w-]+)/$', post_of_season, name='post_of_season'), # /series/Prison_Break/season_5/
url(r'^(?P<serial_slug>[\w-]+)/(?P<season_slug>[\w-]+)/(?P<series_slug>[\w-]+)/$', post_of_serie, name='post_of_serie'), # /series/Prison_Break/season_5/2/
]
this is models.py
class Season(models.Model):
id = models.AutoField(primary_key=True)
name_of_the_season = models.CharField(max_length=40)
slug = models.SlugField(unique=False, blank=True)
name_for_easy_access = models.CharField(max_length=40)
preview_of_season = models.ImageField(upload_to="previews/preview_for_season/", default=None,width_field="width_field", height_field="height_field")
width_field = models.IntegerField(default=150)
height_field = models.IntegerField(default=150)
number_of_released_series = models.IntegerField(default=0)
serial_for_this_season = models.ForeignKey("Serial", on_delete=models.CASCADE, default=True)
a_lot_of_series = models.ManyToManyField("Series", default=None, blank=True)
year = models.IntegerField(default=2017)
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
is_active = models.BooleanField(default=True)
def get_absolute_url(self):
return reverse('series:post_of_season', kwargs=
{'serial_slug': self.serial_for_this_season.slug,
'season_slug': self.slug,
})
def __str__(self):
return "%s" % self.name_for_easy_access
class Meta:
ordering = ["-timestamp"]
verbose_name = 'Season'
verbose_name_plural = 'Seasons'
class Serial(models.Model):
id = models.AutoField(primary_key=True)
rus_name_of_seriall = models.CharField(max_length=40)
eng_name_of_seriall = models.CharField(max_length=40)
slug = models.SlugField(unique=False, blank=True)
number_of_serial = models.DecimalField(max_digits=10, decimal_places=2, default=True)
preview_of_serial = models.ImageField(upload_to="previews/preview_for_serials/", default=None,width_field="width_field", height_field="height_field")
width_field = models.IntegerField(default=0)
height_field = models.IntegerField(default=0)
seasonss = models.ManyToManyField(Season, default=None, blank=True)
timestamp = models.DateField(auto_now_add=True)
end_or_in_proccess = models.ForeignKey(Status, default=None)
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
is_active = models.BooleanField(default=True)
def get_absolute_url(self):
return reverse('series:post_of_serial', kwargs={'serial_slug': self.slug})
def __str__(self):
return "%s" % self.rus_name_of_seriall
class Meta:
ordering = ["-timestamp"]
verbose_name = 'Serial'
verbose_name_plural = 'Serials'
class Series(models.Model):
id = models.AutoField(primary_key=True)
rus_name = models.CharField(max_length=60)
eng_name = models.CharField(max_length=60)
is_active = models.BooleanField(default=True)
serial_of_this_series = models.ForeignKey(Serial, on_delete=models.CASCADE, default=True)
season_of_this_series = models.ForeignKey(Season, on_delete=models.CASCADE, default=True)
number_of_series = models.IntegerField(default=0, blank=True, null=True)
slug = models.SlugField(unique=False, blank=True)
description = models.TextField(max_length=700, blank=True, default=None)
rating = models.FloatField(default=0, blank=True)
timestamp_rus = models.DateTimeField(auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
timestamp_eng = models.CharField(max_length=60)
time_of_series = models.DecimalField(max_digits=10, decimal_places=2, default=0)
def get_absolute_url(self):
return reverse('series:post_of_serie', kwargs=
{'serial_slug': self.serial_of_this_series.slug,
'season_slug': self.season_of_this_series.slug,
'series_slug': self.slug})
def __str__(self):
return "%s | %s" % (self.rus_name, self.number_of_series)
class Meta:
ordering = ["-timestamp_rus"]
verbose_name = 'Series'
verbose_name_plural = 'Series'
Reverse for 'post_of_serial' with arguments '()' and keyword arguments
'{'serial_slug': ''}' not found. 1 pattern(s) tried:
['series/(?P[\w-]+)/$']
(lookup_view_s, args, kwargs, len(patterns), patterns)
django.urls.exceptions.NoReverseMatch: Reverse for 'post_of_serial'
with arguments '()' and keyword arguments '{'serial_slug': ''}' not
found. 1 pattern(s) tried: ['series/(?P[\w-]+)/$']
Change from this
slug = models.SlugField(unique=False, blank=True)
to this
slug = models.SlugField(unique=False)
delete from all slug fields "blank=True" and it's gonna work!
Related
I am trying to filter my many to many variation fields with respect to the product. means, I only want the variations related to the current product to show in the admin page. now its showing all the variations available for every product.
I added formfield_for_manytomany() function to my admin.py but how can I get the current product(id) in the cart or order to filter the variations?
most of the questions in stack overflow Is based on the current user, which is easy to get? but how should I get the specific product(id) that is opened in the admin panel.
admin.py
from django.contrib import admin
from .models import *
from products.models import Variation
class CartAdmin(admin.ModelAdmin):
list_display = ('cart_id', 'date_created')
class CartItemAdmin(admin.ModelAdmin):
list_display = ('user','cart', 'product', 'quantity','is_active')
def formfield_for_manytomany(self, db_field, request, **kwargs):
if db_field.name == "variation":
product = Products.objects.get(id='??') # how I get the current product in the cart or order
kwargs["queryset"] = Variation.objects.filter(product=product.id)
return super().formfield_for_manytomany(db_field, request, **kwargs)
admin.site.register(Cart, CartAdmin)
admin.site.register(CartItem, CartItemAdmin)
CartItem Model
class CartItem(models.Model):
user = models.ForeignKey(CustomUser, on_delete=models.CASCADE, null=True)
cart = models.ForeignKey(Cart, on_delete=models.CASCADE, null=True)
product = models.ForeignKey(Products, on_delete=models.CASCADE)
variation = models.ManyToManyField(Variation, blank=True)
quantity = models.IntegerField()
is_active = models.BooleanField(default=True)
created_date = models.DateTimeField(auto_now_add=True)
def item_total(self):
return self.product.price * self.quantity
def __str__(self):
return self.product.name
Product and Variation Model
class Products(models.Model):
name = models.CharField(max_length=50, unique=True)
slug = AutoSlugField(populate_from='name', max_length=100, unique=True)
isbn = models.CharField(max_length=20, unique=True, blank=True, null=True)
sub_category = models.ForeignKey(SubCategory, on_delete=models.CASCADE)
language = models.ForeignKey(Language, on_delete=models.SET_NULL, null=True)
author = models.CharField(max_length=100)
Publisher = models.CharField(max_length=100, blank=True, default=None)
release_date = models.DateField(blank=True, null=True, default=None)
price = models.IntegerField(default=None)
stock = models.IntegerField(default=None)
is_available = models.BooleanField(default=True)
cover_image = models.ImageField(upload_to='images/products')
image1 = models.ImageField(upload_to='images/products', blank=True, default=None, null=True)
image2 = models.ImageField(upload_to='images/products', blank=True, default=None, null=True)
image3 = models.ImageField(upload_to='images/products', blank=True, default=None, null=True)
description = models.TextField(max_length=2000, blank=True, default=None)
create_date = models.DateTimeField(auto_now_add=True)
modified_date = models.DateTimeField(auto_now=True)
number_of_pages = models.IntegerField(blank=True, null=True)
weight = models.IntegerField(blank=True, null=True)
width = models.IntegerField(blank=True, null=True)
height = models.IntegerField(blank=True, null=True)
spine_width = models.IntegerField(blank=True, null=True)
class Meta:
verbose_name = 'Product'
verbose_name_plural = 'Products'
def get_url(self):
return reverse('product-view', args=[self.slug])
def __str__(self):
return self.name
class Variation(models.Model):
product = models.ForeignKey(Products, on_delete=models.CASCADE)
variation_category = models.CharField(max_length=100, choices=variation_category_choice)
variation_value = models.CharField(max_length=100, choices=variation_value_choice)
is_available = models.BooleanField(default=True)
date_added = models.DateTimeField(auto_now_add=True)
objects = VariationManager()
def __str__(self):
return self.variation_value
I have a django app with following sections
models:
class Report(models.Model):
created_by_user=models.ForeignKey(User,on_delete=models.CASCADE)
planet_name = models.CharField(max_length=100)
outage_id = models.IntegerField(blank=True, default=0)
unit_name = models.CharField(max_length=10, blank=True, null=True)
responsible_group = models.CharField(max_length=50, blank=True)
alarm_num = models.IntegerField(blank=True, default=0)
raised_alarm = models.CharField(max_length=255, blank=True)
start_time = models.DateTimeField(blank=True)
end_time = models.DateTimeField(blank=True)
event_desc = models.TextField(max_length=5000, blank=True)
power_changes = models.FloatField(blank=True)
rel_asset = models.CharField(max_length=255, blank=True)
event_cause = models.TextField(max_length=1000, blank=True)
maintenance_action = models.TextField(max_length=1000, blank=True)
maintenance_cost = models.IntegerField(blank=True)
maintenance_mh = models.IntegerField(blank=True)
maintenance_dc = models.TextField(max_length=5000, blank=True)
serializer:
class ReportSerializer(serializers.ModelSerializer):
created_by_user = serializers.HiddenField(default=serializers.CurrentUserDefault())
class Meta:
model=Report
fields='__all__'
view:
class ReportCreateView(APIView):
def post(self,request, *args, **kwargs):
received_data=ReportSerializer(data=request.data, context = {"request": request})
if received_data.is_valid():
received_data.save()
return Response(received_data.data, status=status.HTTP_201_CREATED)
return Response(received_data.errors,status.HTTP_400_BAD_REQUEST)
but when I send a report by Post method this error rise:
(1048, "Column 'start_time' cannot be null")
How I can fix it?I set blank=True for all fields but why it raise errors?
I'm trying to create a simple car dealership app and i'm stuck. I have searched days and i have tried so many times to fix this but i can't. What i'm doing wrong i don't know and my brain is not working anymore. Thanks for help.
Error:
NoReverseMatch at /
Reverse for 'car_detail' with keyword arguments '{'slug': '2021-ram-1500-trx-crew-cab-4x4-57-box'}' not found. 1 pattern(s) tried: ['(?P<id>[0-9]+)/(?P<slug>[-a-zA-Z0-9_]+)$']
Request Method: GET
Request URL: http://127.0.0.1:8000/
Django Version: 3.2.8
Exception Type: NoReverseMatch
Exception Value:
Reverse for 'car_detail' with keyword arguments '{'slug': '2021-ram-1500-trx-crew-cab-4x4-57-box'}' not found. 1 pattern(s) tried: ['(?P[0-9]+)/(?P[-a-zA-Z0-9_]+)$']
Exception Location: C:\Users*\Desktop\Testdealer\envdealer\lib\site-packages\django\urls\resolvers.py, line 694, in _reverse_with_prefix
Python Executable: C:\Users*\Desktop\Testdealer\envdealer\Scripts\python.exe
Python Version: 3.9.7
Models.py:
from django.db import models
import datetime
from django.urls import reverse
class Car(models.Model):
brand = models.CharField(max_length=100)
CATEGORY = (
('New', 'New'),
('Used', 'Used')
)
slug = models.SlugField(max_length=200, null=True, unique=True)
category = models.CharField(max_length=50, choices=CATEGORY)
image_main = models.ImageField(upload_to='images')
body_style = models.CharField(max_length=100, blank=True)
engine = models.CharField(max_length=100, blank=True)
stock_number = models.IntegerField(blank=True, null=True)
mpg = models.CharField(max_length=100, blank=True)
exterior_color = models.CharField(max_length=100, blank=True)
interior_color = models.CharField(max_length=100, blank=True)
drivetrain = models.CharField(max_length=100, blank=True)
mileage = models.IntegerField(blank=True, null=True)
sold = models.BooleanField(default=False, blank=False)
transmission = models.CharField(max_length=50, blank=True)
YEAR_CHOICES = [(r, r) for r in range(1940, datetime.date.today().year+1)]
year = models.IntegerField(
('year'), choices=YEAR_CHOICES, default=datetime.datetime.now().year)
power = models.IntegerField()
fuel = models.CharField(max_length=50, blank=True)
price = models.CharField(max_length=10, blank=True)
description = models.TextField()
date = models.DateField()
def __str__(self):
return self.brand
def get_absolute_url(self):
return reverse('car_detail', kwargs={'slug': self.slug})
# def get_absolute_url(self):
# return reverse('car_detail', kwargs={
# 'car_id': self.id
# })
class CarImage(models.Model):
"""
The Product Image table.
"""
name = models.CharField(max_length=200, blank=True)
car = models.ForeignKey(
Car, on_delete=models.CASCADE, related_name="car_image")
image = models.ImageField(
verbose_name="image",
help_text="Upload a product image",
upload_to="images/",
default="images/default.png",
)
alt_text = models.CharField(
verbose_name="Alturnative text",
help_text="Please add alturnative text",
max_length=255,
null=True,
blank=True,
)
class Meta:
verbose_name = "Car Image"
verbose_name_plural = "Car Images"
def __str__(self):
return self.name
Views.py:
from django.shortcuts import render, get_object_or_404
from .models import Car, Dealer, CarImage
from django.core.mail import send_mail
def car_detail(request, id, slug):
cars = Car.objects.get(pk=id)
images = CarImage.objects.filter(car_id=id)
context = {'cars': cars, 'images': images}
return render(request, 'car_detail.html', context)
Urls.py:
from django.contrib import admin
from django.urls import path
from django.conf.urls.static import static
from django.conf import settings
from cars import views
..........
path('<int:id>/<slug:slug>', views.car_detail, name="car_detail"),
The .get_absolute_url() [Django-doc] of the Car model only specifies the slug, not the id parameter:
class Car(models.Model):
# ⋮
def get_absolute_url(self):
# add id to the context ↓
return reverse('car_detail', kwargs={'id': self.pk, 'slug': self.slug})
I am trying to make django urls suitable for the seo. I want to send Id and slug in the same url.I don't want to use slug I only want to show in the url.But i am getting an error. My model looks like this:
class Oyunlar(models.Model):
game_id = models.AutoField(primary_key=True)
title = models.CharField(max_length=10000)
platform = models.CharField(max_length=10)
image = models.CharField(max_length=255, blank=True, null=True)
release_date = models.DateField(blank=True, null=True)
click_count = models.IntegerField()
categories=models.ManyToManyField(Kategoriler,through='OyunlarKategoriler')
base_price=models.DecimalField(default=0,max_digits=65535, decimal_places=2)
big_discount=models.BooleanField(default=False)
en_ucuz = models.DecimalField(default=0,max_digits=65535, decimal_places=2)
popularite = models.IntegerField(blank=True, null=True,default=0)
discount_rate = models.DecimalField(max_digits=65535, decimal_places=2)
title_edit = models.CharField(max_length=500, blank=True, null=True)
description = models.CharField(max_length=100000, blank=True, null=True)
steam_id = models.CharField(max_length=1000, blank=True, null=True)
metacritic = models.FloatField(blank=True, null=True)
recommendation = models.BigIntegerField(blank=True, null=True)
full_game = models.BooleanField(blank=True, null=True)
age = models.CharField(max_length=500, blank=True, null=True)
minimum = models.CharField(max_length=10000, blank=True, null=True)
recommended = models.CharField(max_length=10000, blank=True, null=True)
developer = models.CharField(max_length=500, blank=True, null=True)
publisher = models.CharField(max_length=500, blank=True, null=True)
oyun_foto = ArrayField(models.CharField(max_length=10000, blank=True, null=True)) # This field type is a guess.
windows = models.BooleanField(blank=True, null=True)
mac = models.BooleanField(blank=True, null=True)
linux = models.BooleanField(blank=True, null=True)
class Meta:
managed = False
db_table = 'oyunlar'
def __str__(self):
return self.title
Urls.py
path('<int:game_id>/<slug:slug>/',views.oyun,name='detail'),
views.py
def oyun(request,slug,game_id):
print(slug)
oyun=Oyunlar.objects.get(pk=game_id)
comments=Comments.objects.filter(oyunlar=oyun)
game_price=GamePrice.objects.filter(game_id=game_id).order_by('price')
categories = OyunlarKategoriler.objects.filter(game=oyun).values_list('category_id', flat=True)
benzer = Oyunlar.objects.filter(categories__category_id__in=categories, platform=oyun.platform).order_by('-click_count').distinct()[:4]
print(request.method)
if request.method == 'POST':
cf = CommentForm(request.POST or None)
print('burda')
if cf.is_valid():
print('valid')
text = request.POST.get('text')
comment = Comments.objects.create(oyunlar=oyun, user=request.user, text=text)
comment.save()
return redirect(oyun.get_absolute_url())
else:
cf = CommentForm()
return render(request,'product-simple.html',{'oyun':oyun,'game_price':game_price,'benzer':benzer,'comment_form':cf,'comments':comments})
Helper Tag
#register.filter
def slug(value):
return slugify(unidecode(value))
html
<a href="{% url 'detail' i.game_id i.title|slug %}"
But I am getting an error:
Error
Reverse for 'detail' with arguments '(32147,)' not found. 1 pattern(s) tried: ['(?P<game_id>[0-9]+)/(?P<slug>[-a-zA-Z0-9_]+)/$']
I have such a problem that can be turned into a lesson, a hack, with models, and with url-routing, it turns out
Need to be sequenced, that is, by url
Series / serial_slug / season_slug / series_slug /
But to get access to the seasons of the series you need so
Series / serial_slug / season_slug /
It turns out I do not have access to the
series / serial_slug /
season_slug / no access to serial_slug in the Season model, since it is
important for jango that if any model needs access, then the model must
be on top of the requested momme, and thus access to There is no serial model, since it is below the season model, if they
are reversed, it will not work, although the idea should be like this:
In the "Serial" model there is a lot of seasonal that is "ManyToMany" to
the model "Season" that is the logical field there is a model Serial
from above, then there is the model Season, then comes the Series, but
it does not robit! In
the "Season" model there are a lot of series, that is, "ManyToMany" for
the Series model, and to get a consistent url, you need access to all
models, that is, the "Series" model has a season "ForeignKey" for the
"Season" model then The model "Season" has only 1 series again access through
"ForeignKey", if you do so, then it will not work, because, he needs to
have a model on top, to which the query is coming!
I think that this is a great idea for the Django series, namely the
sequence, the dependence of the models, and also the sequence in the
url, through reverse (), that is, the function get_absolute_url (), I
have the code on pastebin, | https://pastebin.com/RAJP6CNv | can you please see if I can throw The
link to my question in stackoverflow, there something explained, but it
did not help, maybe you'll understand, thanks for the lesson!
this is my main url.py
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^series/', include("serials.urls", namespace='series')),
url(r'^', include("serials.urls", namespace='homeview')),
]
this is my app urls.py
from django.conf.urls import include, url
from .views import homeview, post_of_serial, post_of_season, post_of_serie
urlpatterns = [
url(r'^$', homeview, name='homeview'), # /series/
url(r'^(?P<serial_slug>[\w-]+)/$', post_of_serial, name='post_of_serial'), # /series/Prison_Break/
url(r'^(?P<serial_slug>[\w-]+)/(?P<season_slug>[\w-]+)/$', post_of_season, name='post_of_season'), # /series/Prison_Break/season_5/
url(r'^(?P<serial_slug>[\w-]+)/(?P<season_slug>[\w-]+)/(?P<series_slug>[\w-]+)/$', post_of_serie, name='post_of_serie'), # /series/Prison_Break/season_5/2/
]
this is my models.py
from django.db import models
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.core.urlresolvers import reverse
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
import datetime
class Status(models.Model):
name = models.CharField(max_length=120)
is_active = models.BooleanField(default=True)
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
def __str__(self):
return "|{0}| |{1}|".format(self.name, self.is_active)
class Meta:
ordering = ["-timestamp"]
verbose_name = 'Staus'
verbose_name_plural = 'Statuses'
class Season(models.Model):
id = models.AutoField(primary_key=True)
name_of_the_season = models.CharField(max_length=40)
slug = models.SlugField(unique=False, blank=True)
name_for_easy_access = models.CharField(max_length=40)
preview_of_season = models.ImageField(upload_to="previews/preview_for_season/", default=None,width_field="width_field", height_field="height_field")
width_field = models.IntegerField(default=150)
height_field = models.IntegerField(default=150)
number_of_released_series = models.IntegerField(default=0)
year = models.IntegerField(default=2017)
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
is_active = models.BooleanField(default=True)
def get_absolute_url(self):
return reverse('series:post_of_season', kwargs=
{'serial_slug': self.serial.slug,
'season_slug': self.slug,
})
def __str__(self):
return "%s" % self.name_for_easy_access
class Meta:
ordering = ["-timestamp"]
verbose_name = 'Season'
verbose_name_plural = 'Seasons'
class Serial(models.Model):
id = models.AutoField(primary_key=True)
rus_name_of_seriall = models.CharField(max_length=40)
eng_name_of_seriall = models.CharField(max_length=40)
slug = models.SlugField(unique=False, blank=True)
number_of_serial = models.DecimalField(max_digits=10, decimal_places=2, default=True)
preview_of_serial = models.ImageField(upload_to="previews/preview_for_serials/", default=None,width_field="width_field", height_field="height_field")
width_field = models.IntegerField(default=0)
height_field = models.IntegerField(default=0)
seasonss = models.ManyToManyField(Season, default=None, blank=True)
timestamp = models.DateField(auto_now_add=True)
end_or_in_proccess = models.ForeignKey(Status, default=None)
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
is_active = models.BooleanField(default=True)
def get_absolute_url(self):
return reverse('series:post_of_serial', kwargs={'serial_slug': self.slug})
def __str__(self):
return "%s" % self.rus_name_of_seriall
class Meta:
ordering = ["-timestamp"]
verbose_name = 'Serial'
verbose_name_plural = 'Serials'
class Series(models.Model):
id = models.AutoField(primary_key=True)
rus_name = models.CharField(max_length=60)
eng_name = models.CharField(max_length=60)
is_active = models.BooleanField(default=True)
serial_of_this_series = models.ForeignKey(Serial, on_delete=models.CASCADE, default=True)
season_of_this_series = models.ForeignKey(Season, on_delete=models.CASCADE, default=True)
number_of_series = models.IntegerField(default=0, blank=True, null=True)
slug = models.SlugField(unique=False, blank=True)
description = models.TextField(max_length=700, blank=True, default=None)
rating = models.FloatField(default=0, blank=True)
timestamp_rus = models.DateTimeField(auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
timestamp_eng = models.CharField(max_length=60)
time_of_series = models.DecimalField(max_digits=10, decimal_places=2, default=0)
def get_absolute_url(self):
return reverse('series:post_of_serie', kwargs=
{'serial_slug': self.serial_of_this_series.slug,
'season_slug': self.season_of_this_series.slug,
'series_slug': self.slug})
def __str__(self):
return "%s | %s" % (self.rus_name, self.number_of_series)
class Meta:
ordering = ["-timestamp_rus"]
verbose_name = 'Series'
verbose_name_plural = 'Series'
You can fix these by putting string instead of class like
Change
models.ForeignKey(Serial)
to
models.ForeignKey("Serial")