Django - form with foreign key to model with gallery - python

I have models like this:
class Picture(models.Model):
source = models.ImageField(null=True, blank=True) #TODO: check the field type, correct if needed
def __str__(self):
return "%s" % self.pk
class News(models.Model):
content = MartorField()
title = models.CharField(max_length=512)
creation_date = models.DateField(default=timezone.now)
publish_date = models.DateField(null=True, blank=True)
picture_id = models.ForeignKey('Picture', null=True, blank=True, on_delete=models.CASCADE)
class Meta:
verbose_name_plural = "News"
def __str__(self):
return "%s" % self.title
And I'm using CreateView and UpdateView. When I use {{ form.as_p }} I have a problem, because picker of image is showing only id - not image. I'm looking for some widget or workaround to fix this problem.

Related

For blog post i used tags by many_to_many filed. Now i try to use Django_Taggit for tag field, but i face some error while migrate

Old MODELS.py
when use tags by many_to_many fields
class Tag(models.Model):
tag_name = models.CharField(max_length=64, unique=True)
tag_slug = models.SlugField(max_length=64, unique=True)
created_on = models.DateTimeField(auto_now_add=True)
created_by = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
def __str__(self):
return self.tag_name
def get_absolute_url(self):
return reverse("news:tag-detail", kwargs={"slug": str(self.tag_slug)})
class News(models.Model):
title = models.CharField(max_length=192, unique=True)
slug = models.SlugField(max_length=192, unique=True)
cover_photo = models.ImageField(upload_to='news', blank=True, null=True)
summary = models.CharField(max_length=280)
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='post_author')
updated_on = models.DateTimeField(auto_now=True)
content = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
status = models.IntegerField(choices=STATUS, default=1)
# tags = models.ManyToManyField(Tag, blank=True, related_name='post_tag')
class Meta:
ordering = ['-created_on']
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("news:post", kwargs={"slug": str(self.slug)})
current models.py
After install Django_Taggit
i remove tags model and rewrite tags line
class News(models.Model):
title = models.CharField(max_length=192, unique=True)
slug = models.SlugField(max_length=192, unique=True)
cover_photo = models.ImageField(upload_to='news', blank=True, null=True)
summary = models.CharField(max_length=280)
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='post_author')
updated_on = models.DateTimeField(auto_now=True)
content = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
status = models.IntegerField(choices=STATUS, default=1)
tags = TaggableManager()
class Meta:
ordering = ['-created_on']
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("news:post", kwargs={"slug": str(self.slug)})
Also i remove tags from view.py and urls path and update html
but when i try to 'python manage.py migrate' i face this error
ValueError: Cannot alter field news.News.tags into news.News.tags - they are not compatible types (you cannot alter to or from M2M fields, or add or remove through
= on M2M fields)
First remove the tags field and (makemigrations->migrate), then as you don't have tags as a field anymore add the new taggit field and again (makemigrations->migrate).
If you want to save the current tags, I can think of couple of options.
Create new field for example tags_taggit, and then run a script to translate the current tags into the new tags_taggit field. Then proceed with the steps I told you first
Create fixtures, then run a script to iterate over the fixtures and save the tags into the new field.

Accessing other model field when validating model field in Django

So I have a Django auctions app, which has 4 models: Users, Listings, Bids, Comments.
When a user tries to place a bid on some listing, I want to check whether bid_amount field in Bid model is smaller than start starting_bid field in Listing model. Also, I wanted to ask, what is the best practice for this kinda stuff? AFAIK, you can validate a form field in forms.py. Thanks!
models.py
class Listing(models.Model):
"""Auction listing"""
user = models.ForeignKey(User, verbose_name='user owner', on_delete=models.CASCADE, related_name="usr_listings")
title = models.CharField(max_length=64)
description = models.TextField(max_length=160)
starting_bid = models.PositiveIntegerField()
bids_number = models.PositiveIntegerField(default=1)
img_url = models.URLField("Image URL", max_length=200, blank=True)
category = models.CharField(max_length=64, blank=True)
date_listed = models.DateTimeField(default=timezone.now)
class Meta:
verbose_name = 'auction listing'
ordering = ['-date_listed']
def __str__(self):
return self.title
def get_absolute_url(self):
print('loading... get_absolute_url')
return reverse('listing_detail', kwargs={'pk': self.pk})
class Bid(models.Model):
"""Bids made on auction listing"""
listing = models.ForeignKey(Listing, on_delete=models.CASCADE, related_name="listing_bids")
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="user_bidder")
bid_amount = models.PositiveIntegerField(default=None)
class Meta:
verbose_name = 'Bid'
def __str__(self):
return f'{self.bid_amount} by {self.user} on {self.listing}'
def clean(self):
super().clean()
# do something to access Listing.starting bid, and Listing.user
adding this to the clean method of Bid solve the problem for you.
from django.core.exceptions import ValidationError
...
if self.bid_amount < self.listing.starting_bid:
raise ValidationError("bid_amount must be greater than or equal to starting_bid of the listing")

How do i create a category and subcategories

This is my Item Model, how do i create a Category and Subcategories like; Man-clothing-shirt and Woman-clothing-shirt.
class Item(models.Model):
title = models.CharField(max_length=250)
company_name = models.CharField(max_length=50, blank=True)
product_you_may_like = models.ForeignKey(ProductYouMayLike, null=True, blank=True,
on_delete=models.CASCADE)
image = models.ImageField(null=True)
price = models.IntegerField()
old_price = models.IntegerField(null=True, blank=True)
shipping_amount = models.IntegerField()
percentage_off = models.IntegerField(null=True, blank=True)
description = models.TextField(null=True, blank=True)
specification = models.TextField(null=True, blank=True)
product_type = models.CharField(max_length=20, choices=PRODUCT_TYPE, null=True, blank=True)
slug = AutoSlugField(populate_from='title', unique=True)
timestamp = models.DateTimeField(auto_now_add=True)
active = models.BooleanField(default=True)
class Meta:
ordering = ['-timestamp']
db_table = 'items'
verbose_name_plural = 'Items'
def __str__(self):
return self.title
You may make use of django-mptt to create a tree of categories and then have a foreign-key to this model in the item model.
class Category(MPTTModel):
name=models.CharField(max_length=75,null=False,blank=False, unique=True)
parent=TreeForeignKey('self', null=True, blank=True, related_name='children', db_index=True, on_delete=models.CASCADE)
I don't know how you wrote your MenShirtCategory, but the name let me think that you mixed up class and instance.
Usually, you may have a Category model (or ItemCategory, if these caterogies are specific to Item) written this way:
class Category(models.Model):
name = models.CharField(max_length=..., ...) # men shirts will be the name
parent = models.ForeignKey('self', null=True, blank=True,
on_delete=...,
related_name='children')
And then connect it to your Item model:
class Item(models.Model):
category = models.ForeignKey(Category, null=True, blank=True,
on_delete=models.CASCADE)
By using 'self' in the parent field of the Category model, you can implement the concept of nested categories.
Of course, you may need to ensure manually that you don't create cycles (A child of B child of A), as the database (and then models) cannot do it for you. While doing this, you may also need to check that a category cannot be it's own parent.
I was able to solve the problem by adding a model Category and also A foreignkey to Item model. Example,
class Item(models.Model):
category = models.ForeignKey(Category, null=True,blank=True,
on_delete=models.CASCADE)
class Category(models.Model):
name = models.CharField(max_length=250)
In model add men_shirt in Category, then save.
In views.py:
def template(request):
category = Category.objects.filter(name="men_shirt")
context = { 'category':category }
return render(request, "template.html", context)
In template:
{% for category in category %}
{% for item in category.item.all %}
<h1>This will display all content in item by the name you filtered in views.py </h1>
{% endfor %}
{% endfor %}

AttributeError; Dynamic url for list of charts by category issue (queryset filter)

Django 'CategorisedListView' object has no attribute 'slug' or Page not found (error 404) issue
I'm on Django 2.0, using generic class list view. I have tried dynamic url based on slug and queryset filter on slug to get list of charts by category.
Please help! I've been stuck here for a couple of days since.
views.py
class CategoriesView(generic.ListView):
template_name = 'Bokeh/categories.html'
context_object_name = 'all_categories'
def get_queryset(self):
return Category.objects.all()
class CategorisedListView(generic.ListView):
model = Category
template_name = 'categories/list_of_charts_by_category.html'
context_object_name = 'categorised'
def get_queryset(self):
self.category = get_object_or_404(Category, name = self.kwargs['slug'])
return Chart.objects.filter(category=self.slug)
models.py
class Category(models.Model):
name = models.CharField(max_length=100)
image_file = models.ImageField(default=None, unique=True)
slug = models.SlugField(max_length=100, unique=True)
parent = models.ForeignKey('self', on_delete=models.PROTECT, blank=True, null=True, related_name='children')
def __str__(self):
return self.name
def get_absolute_url(self):
return '{slug}/'.format(slug=self.slug)
class Meta:
ordering = ('name',)
verbose_name = 'Category'
verbose_name_plural = 'Categories'
class Chart(models.Model):
name = models.CharField(max_length=250)
slug = models.SlugField(max_length=250, unique=True)
description = models.TextField(max_length=250)
url = models.URLField(default=None, blank=True)
embed_url = models.TextField(default=None, blank=True)
image_file = models.ImageField(default=None, unique=True)
code_file = models.FileField(default=None, blank=True, unique=True)
chart_library = models.CharField(max_length=250)
author = models.ForeignKey(User, on_delete=models.CASCADE, default=1)
tag = TaggableManager()
category = models.ForeignKey(Category, on_delete=models.CASCADE, blank=True, null=True)
def __str__(self):
return self.name + ' - ' + self.chart_library
def get_absolute_url(self):
return reverse('Bokeh:detail', kwargs={'pk': self.pk})
def read_file(self):
data = self.code_file.path
with open(self.code_file.path, 'r', encoding='UTF-8') as data:
content = data.read()
return content
class Meta:
ordering = ('name',)
urls.py
path("categories/", views.CategoriesView.as_view(), name='categories'),
# /Bokeh/categories/<category_slug>
path("categories/<slug:slug>/", views.CategorisedListView.as_view(), name='list_of_charts_by_category'),
it is supposed to query the database when a specific category is clicked and return the list of charts categorised under that specific category. However, the page throws 'CategorisedListView' object has no attribute 'slug'
The lookup you're doing in get_queryset() isn't quite right. Firstly, you seem to be looking up the Category by name rather than by the slug. Then you try and filter the Charts using their category attribute, but instead of passing the category you pass a non-existent attribute self.slug.
Try changing the implementation to this:
def get_queryset(self):
# Lookup the Category using it's slug attribute, not name, and assign to local variable
category = get_object_or_404(Category, slug=self.kwargs['slug'])
# Now lookup the Charts using the category we just looked up
return Chart.objects.filter(category=category)

Django: When saving issue

I's using django 1.6 and have a model for a blog but when saving the content I get category id can not be blank but I don't understand this error. I have tried looking at the code trying different things but it doesn't seem to be working.
class Category(models.Model):
title = models.CharField(max_length=100)
slug = models.SlugField(max_length=100)
description = models.TextField(null=True, blank=True)
class Meta:
verbose_name_plural = "Categories"
def __unicode__(self):
return '%s' % self.title
#permalink
def get_absolute_url(self):
return ('view_category', None, {'slug': self.slug})
class Blog(models.Model):
user = models.ForeignKey(User)
title = models.CharField(max_length=100, unique=True)
slug = models.SlugField(max_length=100, unique=True)
description = models.TextField(max_length=2000)
extended = models.TextField(null=True, blank=True)
category = models.ForeignKey(Category)
created = models.DateTimeField(auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
class Meta:
verbose_name = 'Blog post'
verbose_name_plural = 'Blog posts'
ordering = ('-updated',)
def __unicode__(self):
return '%s' % self.title
#permalink
def get_absolute_url(self, ):
return('view_questions', None, {'slug': self.slug,})
def save(self):
super(Blog, self).save()
if not self.slug:
self.slug = '%d/%s' % (
self.pk, slugify(self.title)
)
super(Blog, self).save()
when saving the content I get category id can not be blank but I don't
understand this error.
category = models.ForeignKey(Category)
That line means that a blog post must belong to a category. In your blog table, the category foreign key is called category_id.
You can either make sure to add a category; blog.category = Category.objects.get(...) for example OR you can make the category optional:
category = models.ForeignKey(Category, blank=True, null=True)

Categories