I have models like this :
class Region(models.Model):
region_parent = models.ForeignKey(
"self", blank=True, null=True, on_delete=models.CASCADE)
name = models.CharField(max_length=255)
title = models.CharField(max_length=255)
description = RichTextField()
description_on_list = RichTextField(blank=True)
thumbnail = models.ImageField(
upload_to="thumbnail-region", blank=True, max_length=255)
sidebar = RichTextField(blank=True)
ad_manager = models.TextField(blank=True)
meta_keywords = models.TextField(blank=True)
logo_on_navbar = models.ImageField(
upload_to="logo-on-navbar/", blank=True, max_length=255)
display_on_navbar = models.BooleanField(default=True)
slug = models.SlugField(unique=True)
def get_absolute_url(self):
if self.region_parent is not None:
return reverse('vineyards:region', kwargs={'parent': self.region_parent.slug, 'region': self.slug})
else:
return reverse('vineyards:region-without-parent', kwargs={'region': self.slug})
class Vineyard(models.Model):
name = models.CharField(max_length=255)
text = RichTextField()
rating = models.FloatField()
custom_overlay = models.ImageField(
upload_to="custom-rating/", blank=True, max_length=255)
google_map = models.TextField()
wine_rg_url = models.URLField(blank=True)
wine_rg = models.CharField(max_length=255)
wines_url = models.URLField(blank=True)
wines = models.CharField(max_length=255)
size = models.CharField(max_length=255)
grapes = models.CharField(max_length=255)
owner_url = models.URLField(blank=True)
owner = models.CharField(max_length=255)
visits = models.CharField(max_length=255)
region = models.ForeignKey(Region, on_delete=models.CASCADE)
regions = models.ManyToManyField(
Region, blank=True, related_name="regions")
cover = models.ImageField(upload_to="vineyard/", max_length=255)
sidebar = RichTextField(blank=True)
ad_manager = models.TextField(blank=True)
meta_keywords = models.TextField(blank=True)
top_slider = models.BooleanField(default=False)
cover_slider = models.BooleanField(default=False)
hide_rating = models.BooleanField(default=False)
slug = models.SlugField(unique=True)
def get_absolute_url(self):
if self.region.region_parent is not None:
return reverse('vineyards:detail', kwargs={'parent': self.region.region_parent.slug, 'region': self.region.slug, 'slug': self.slug})
else:
return reverse('vineyards:detail-without-parent', kwargs={'region': self.region.slug, 'slug': self.slug})
And this is my urls.py:
app_name = 'vineyards'
urlpatterns = [
path('<str:parent>/<str:region>/<slug:slug>/form/',
rr_form, name="detail-form"),
path('<str:region>/<slug:slug>/form/',
rr_form, name="detail-without-parent-form"),
path('<str:parent>/<str:region>/', vineyard_region, name="region"),
path('<str:region>/', vineyard_region, name="region-without-parent"),
path('<str:parent>/<str:region>/<slug:slug>/',
vineyard_detail, name="detail"),
path('<str:region>/<slug:slug>/',
vineyard_detail, name="detail-without-parent"),
]
The problem is, I can't access the last 2 paths (vineyards: detail, vineyards: detail-without-parent). I think the problem is in the order of the urls. I have tried different order but the result is always only one or some urls are working, not all.
Is it possible to have a url with the same path like this: slug/slug/ ? Or should I split the url into two different files? Any suggestions?
Thanks.
Your url paths must be unique. How should Django otherwise know which path to use for the request?
If several paths match the url pattern, Django will use the first matching path.
Use unique url patterns in your paths. For example,
#this is just an example, adjust as it makes sense by your app logic
path('parent/<str:parent>/<str:region>/<slug:slug>/',
vineyard_detail, name="detail"),
path('detail/<str:region>/<slug:slug>/',
vineyard_detail, name="detail-without-parent"),
Related
I have below models and form.
Brand > Section > Category > Article.
I can pull the existing data out of the database however I have hit a wall. I am trying to create a new article or update an existing article but I'm not sure how I can update the brand, then the Section. The Category I can update and it is connected directly to the Article model. I have been thinking about this for a few days now and tried different models but ultimately i can't think of the best way to connect the models and have them update in the model.
class Brand(models.Model):
def brand_image(instance, filename):
return 'uploads/brand/{0}/{1}'.format(instance.title, filename)
title = models.CharField(max_length=50, unique=True, blank=True, null=True)
image = models.ImageField(upload_to=brand_image, null=True, blank=True)
slug = AutoSlugField(populate_from='title', unique_with='title', blank=True, null=True)
my_order = models.PositiveIntegerField(default=0, blank=False, null=False)
class Meta:
ordering = ['my_order']
def __str__(self):
return self.title or ''
def get_absolute_url(self):
return reverse('brand-list', kwargs={'brand_slug': self.slug})
class Section(models.Model):
title = models.CharField(max_length=50,unique=True, blank=True,null=True)
slug = AutoSlugField(populate_from='title', unique_with='title',blank=True,null=True)
brand = models.ForeignKey(Brand, on_delete=models.CASCADE, related_name='section', blank=False, null=False)
my_order = models.PositiveIntegerField(default=0, blank=False, null=False)
class Meta:
ordering = ['my_order']
def __str__(self):
return self.title or ''
def get_absolute_url(self):
return reverse('section-list', kwargs={'section_slug': self.slug})
class Category(models.Model):
title = models.CharField(max_length=50, blank=True,null=True)
slug = AutoSlugField(populate_from='title', unique_with='title',blank=True,null=True)
my_order = models.PositiveIntegerField(default=0, blank=False, null=False)
section = models.ForeignKey(Section, on_delete=models.CASCADE,related_name='category', blank=False ,null=False)
class Meta:
ordering = ['my_order']
def __str__(self):
return self.title or ''
def get_absolute_url(self):
return reverse('category-list', kwargs={'category_slug': self.slug})
class Article(models.Model):
title = models.CharField(max_length=100, unique=True, db_index=True)
description = models.CharField(max_length=100, blank=True, null=False)
category = models.ForeignKey(Category, on_delete=PROTECT, related_name='article', null=False, default=1)
slug = AutoSlugField(populate_from='title', unique_with='created__month')
content = HTMLField(null=True,blank=True)
internal = models.BooleanField(default=False)
status = models.CharField(max_length=30, choices=STATUS_CHOICES, default='Draft')
author = models.ForeignKey(User, related_name='author' ,on_delete=PROTECT,null=True)
updated_by = models.ForeignKey(User, related_name='updated_by',on_delete=PROTECT,null=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
video = models.FileField(blank=True, null=True, upload_to='articles/videos')
favourites = models.ManyToManyField(User, related_name='art_favourite', default=None, blank=True)
tags = TaggableManager(related_name='tags', help_text='Comma or space separated list', blank=True)
pinned = models.BooleanField(default=False)
def __str__(self) -> str:
return self.title
def get_absolute_url(self):
return reverse('articles-detail', kwargs={'article_slug': self.slug})
class ArticleForm(forms.ModelForm):
title = forms.CharField(label='Article Title', max_length=100,)
description = forms.CharField(label='Description', max_length=100,required=False)
content = forms.CharField(label='Article Content',widget=CKEditorUploadingWidget(attrs={'cols': 80, 'rows': 30}))
video = forms.FileField(help_text="Valid file Extension - .mp4", required=False, validators=[validate_file_extension])
category = GroupedModelChoiceField(queryset=Category.objects.exclude(section=None).order_by('section'),choices_groupby='section')
internal = forms.BooleanField(required=False, help_text='Is this for internal use only?', label='Internal Article')
class Meta:
model = Article
exclude = ['slug','author','created','updated','updated_by','favourites','votes','views','section']
widgets = {"tags": TagWidget(attrs={"data-role": "tagsinput"})}
Any help or guidance would be greatly appreciated.
Your Article model has a foreign key link to Section for some reason. However your stated heirarchy and models use the following one-to-many relations, which creates a direct link up the chain.
Brand < Section < Category < Article.
This means that by choosing the Category you could also choose Brand and Section. If your Article had a foreign key link to Category instead, then all the information above about groups above Article could be obtained via the article, eg, article.category__section__brand. Changing the category would, by default, update section and brand. You could do this in a single dropdown that contained Category.objects.all - perhaps with the dropdown option text also containing brand and section info for clarity and sorting purposes.
Have the following models
class FootballWebsite(models.Model):
"""Football service website."""
url = models.URLField, unique=True)
#football service
id = models.CharField(primary_key=True,
#is this domain blocked
blocked = models.BooleanField(default=False)
#is it online or offline
online = models.BooleanField(default=False)
updated = models.DateTimeField(auto_now=True, auto_now_add=True)
sub_categories = models.ForeignKey(SubCategory, default=1)
referral = models.TextField(blank=True)
mirror = models.ForeignKey('FootballWebsite', blank=True, null=True)
rank = models.PositiveIntegerField(default=0, blank=True, null=True)
screenshot = models.BooleanField(default=False)
class Meta:
"""Meta class."""
app_label = 'ahmia'
def __unicode__(self):
return u'%s' % (self.url)
"""The datetime when the football service was last seen online"""
try:
return self.footballwebsitestatus_set.filter(online=True).latest('time').time
except FootballWebsiteStatus.DoesNotExist:
return None
class FootballWebsiteDescription(models.Model):
"""Football service website description."""
about = models.ForeignKey(Footballebsite)
title = models.TextField(blank=True, null=True)
keywords = models.TextField(blank=True, null=True)
description = models.TextField(blank=True, null=True)
relation = models.URLField(blank=True, null=True)
subject = models.TextField(blank=True, null=True)
type = models.TextField(blank=True, null=True)
updated = models.DateTimeField(auto_now=True, auto_now_add=True)
language = models.TextField(null=True, blank=True)
contactInformation = models.TextField(null=True, blank=True)
officialInfo = models.BooleanField(default=False)
slug = AutoSlugField(populate_from=['title'], allow_duplicates=True, null=True)
class Meta:
"""Meta class."""
app_label = 'ahmia'
def __unicode__(self):
return unicode(self.about.url)
def save(self, *args, **kwargs):
self.slug = slugify(self.title)
super(FootballebsiteDescription, self).save(*args, **kwargs)
def __unicode__(self):
return u'%s' % (self.title)
I have a huge amount of links, and i would like to bulk assign them into a category or mark them as blocked based on identical title slug.
Managed to at least get a list of title_slugs with the code below, but the following step, i would like to get an inline list with all sites that have an identical title_slug and bulk assign those all in their a category
class FootballWebsiteInline(admin.TabularInline):
model = FootballWebsite
class FootballWebsiteDescriptionAdmin(admin.ModelAdmin):
list_display = ['show_slug']
def show_slug(self, obj):
return format_html("<a href='{url}'>{url}</a>", url=obj.slug)
inlines = [
FootballWebsiteInline,
]
Above code obviously doesn' t work, since the title slug which can appear many times is not a primary key.
Is it possible to get an inline list based on the title slug in this case which is not a primary key at all, or am i going about this the wrong way?
When possible at all, some further tweaking would be to group the identical title slugs
i want to fetch the item of related subcategories but i am unable to fetch the items from that subcategories it is showing me the error
AttributeError: 'Subcategories' object has no attribute 'item'
so here is my code
my models
class Subcategories(models.Model):
categories = models.ForeignKey(Categories, on_delete=models.CASCADE, related_name='our_categories')
name = models.CharField(max_length=200, blank=False)
joined_date = models.DateTimeField(default=timezone.now,editable=False)
update_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name
class Item(models.Model):
categories = models.ForeignKey(Categories, on_delete=models.CASCADE,)
subcategories = models.ForeignKey(Subcategories, on_delete=models.CASCADE, related_name='products')
can_buy = models.ForeignKey(For, on_delete=models.CASCADE,)
name = models.CharField(max_length=200, blank=False)
contain_size = models.CharField(max_length=10, blank=True)
first = models.ImageField(upload_to='items', blank=False)
second = models.ImageField(upload_to='items', blank=True)
third = models.ImageField(upload_to='items', blank=True)
fourth = models.ImageField(upload_to='items', blank=True)
fifth = models.ImageField(upload_to='items', blank=True)
item_vedio = models.FileField(upload_to='item_vedio', blank=True)
offered_price = models.FloatField(blank=False,)
actual_price = models.FloatField(blank=False)
about = models.TextField(blank=False, default="about" )
offer = models.CharField(max_length=4, blank=True)
def __str__(self):
return self.name
my urls.py
urlpatterns = [
path('<int:subcategory_id>/products/',Product.as_view(),name='product' ),
]
my views.py
class Product(View):
def get(self, request,):
category_list = Categories.objects.all()
return render (request, 'products.html', {'category_list': category_list })
def get(self, request, subcategory_id):
subcategory = get_object_or_404(Subcategories, pk=subcategory_id)
products = subcategory.item.all()
return render (request, 'products.html',{"subcategory_list" : products })
any idea what causing the issue and thank you for your time
The related name is products for subcategories Foreign key in Item model.
subcategory.products.all()
I created models for companies in my new application in django and have also created the instance for it to show detail page for each company. But when a company is clicked, it shows the id of the company instead of the name in URL like this: http://127.0.0.1:8000/companies/2/
is there a way I can make it return the company name instead like this: http://127.0.0.1:8000/companies/stackoverflow/
this is the code for my model and am using function based views for this:
class Company(models.Model):
Online_Merchant = 'merch'
Education = 'edu'
Transportation = 'trans'
Hospitalism = 'hosp'
Healthcare = 'health'
Construction = 'const'
Blog = 'blog'
Finance = 'fin'
Media = 'media'
Government_Agency = 'agency'
Other = 'other'
Manufacturing = 'manufacturing'
sector = [
(Online_Merchant, 'Online Merchant'),
(Education, 'Education'),
(Transportation, 'Transportation'),
(Hospitalism, 'Hospitalism'),
(Healthcare, 'Healthcare'),
(Construction, 'Construction'),
(Blog, 'Blog'),
(Finance, 'Finance'),
(Media, 'Media'),
(Manufacturing, 'Manufacturing'),
(Government_Agency, 'Government Agency'),
(Other, 'Other')
]
Free = 'Free'
Premium = 'Premium'
package = [
(Free, 'Free'),
(Premium, 'Premium')
]
user = models.ForeignKey(User, null=True, blank=True, on_delete=models.SET_NULL, verbose_name='Company User')
company_sector = models.CharField(max_length=30, choices=sector, default=Online_Merchant, verbose_name='Sector')
company_name = models.CharField(max_length=100)
company_description = models.TextField()
company_logo = models.ImageField(upload_to='company_logos', blank=True, null=True)
company_address = models.TextField(max_length=2000)
rating_array = ArrayField(models.IntegerField(), size=0, default=list)
average_rating = Int_max.IntegerRangeField(default=0, verbose_name='Avg', min_value=1, max_value=5)
total_views = models.IntegerField(default=0)
company_website = models.CharField(max_length=500, blank=True, null=True)
company_email = models.EmailField(max_length=500, blank=True, null=True)
company_phone = models.CharField(max_length=500)
package_chosen = models.CharField(max_length=8, choices=package, default=Free)
company_views = models.IntegerField(default=0)
featured = models.BooleanField(default=False)
advert = models.BooleanField(default=False)
premium = models.BooleanField(default=False)
def get_absolute_url(self):
"""Returns the url to access a particular instance of the model."""
return reverse("detail", kwargs={ "id": self.id })
def __str__(self):
return self.company_name
def __repr__(self):
return self.company_name
SlugField is designed for this. the django admin will help populate it as well.
models.py
class Company(models.Model):
...other model fields...
company_slug = models.SlugField(max_length=255, allow_unicode=True)
def get_absolute_url(self):
"""Returns the url to access a particular instance of the model."""
return reverse("detail", kwargs={ "slug": self.company_slug })
admin.py
class CompanyAdmin(admin.ModelAdmin):
prepopulated_fields = {"company_slug": ("company_name",)}
...admin code...
and to use it in a query:
company = Company.objects.get(company_slug=kwargs.get('company_slug')
urls.py
urlpatterns = [ path('<slug:company_slug>/', views.dynamic_url, name='detail'), ]
I have different django models which are identical e.g
ItemCategory
InventoryCategory
MenuCategory
ExpenseCategory
All of these models carry same attributes.
I want to use single html page which is category_list.html for displaying these models as list. I don't want to use different pages like item_category_list.html, inventroy_category_list.html, menu_category_list.html and so on. Every page contains page header which is actual kind of title of page represented in h1 tag. I want to change with respect to currently loaded page.
Note: I am using Generic Views for Listing Items and I am currently using context for recognizing which view is sending response.
Any help would be appreciated.
views.py
class ItemCategoryList(ListView):
model = ItemCategory
template_name = 'app/category_list.html'
def get_context_data(self, **kwargs):
# Call the base implementation first to get a context
context = super().get_context_data(**kwargs)
# Add in a QuerySet of all the books
context['page'] = 'Item'
return context
class InventoryCategoryList(ListView):
model = InventoryCategory
template_name = 'app/category_list.html'
class ExpenseCategoryList(ListView):
model = ExpenseCategory
template_name = 'app/category_list.html'
models.py
class ItemCategory(models.Model):
name = models.CharField(max_length=30)
description = models.CharField(max_length=300, null=True, blank=True)
image = models.ImageField(upload_to="uploads/item_categories/", null=True, blank=True)
is_active = models.BooleanField(default=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now_add=True)
class InventoryCategory(models.Model):
name = models.CharField(max_length=30)
description = models.CharField(max_length=300, null=True, blank=True)
image = models.ImageField(upload_to="uploads/inventory_categories/", null=True, blank=True)
is_active = models.BooleanField(default=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now_add=True)
class ExpenseCategory(models.Model):
name = models.CharField(max_length=30)
description = models.CharField(max_length=300, null=True, blank=True)
image = models.ImageField(upload_to="uploads/expense_categories/", null=True, blank=True)
is_active = models.BooleanField(default=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now_add=True)
Not class based but my solution for this simply would be :
models.py:
class Category(models.Model):
name = models.CharField(max_length=30)
description = models.CharField(max_length=300, null=True, blank=True)
image = models.ImageField(upload_to="uploads/categories/", null=True, blank=True)
is_active = models.BooleanField(default=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now_add=True)
urls.py:
url(r'^(?P<category>\w+)/$', views.ItemCategoryList, name='category')
home.html:
Item Category
Inventory Category
category_list.html:
{% block title %}{{category.name}}{% endblock %}
{% for l in list %}
{{l}}
{% endfor%}
views.py:
def ItemCategoryList(request, category):
list = Category.objects.filter(name=category)
category = category
context{
'list':list,
'category':category
}
return render(request, 'app/category_list.html',context)