Creating a unique (attribute) title in a Model - python

I have a blog project and users can create posts with similar titles, How can I prevent a user or even the admin from proceeding without getting an error that the title already exists so that I can avoid future errors in the website such as get() returned more than one Post-it returned 2!
I have tried to use class meta for unique together but still, post was saved with the same title
Here is the post model
class Post(models.Model):
designer = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=100)
slug = models.SlugField(blank=True, null=True, max_length=120)
def __str__(self):
return self.title
class Meta:
unique_together = ('title', 'slug')

You can add unique=True
title = models.CharField(max_length=100, unique=True)
See the docs here.

Related

Multi-table inheritance and two many to many via through model not working in admin inline

I'm trying to create navigation menu from the django admin as per user's requirement.
The Model look like this:
class MenuItem(models.Model):
title = models.CharField(max_length=200, help_text='Title of the item')
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
is_published = models.BooleanField(default=False)
def __str__(self):
return self.title
class Page(MenuItem):
"""
To display non-hierarchical pages such as about us, or some page in menu
"""
slug = models.SlugField(max_length=200, unique=True, help_text='End of url')
content = HTMLField(help_text='Contents of the page')
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING)
class Category(MenuItem):
"""
For hierarchical display eg. in navigation menu use Category and Articles.
"""
slug = models.SlugField(max_length=200, unique=True, help_text='End of url')
class Meta:
verbose_name_plural = 'categories'
Page and Category can be different types of menu items, so, I used inheritance. Now I want to bind the MenuItem to a Menu, hence I added two more models below.
class Menu(models.Model):
title = models.CharField(max_length=200, unique=True, help_text='Name of the menu.')
is_published = models.BooleanField(default=False)
item = models.ManyToManyField(MenuItem, through='MenuLevel', through_fields=['menu', 'menu_item'])
def __str__(self):
return self.title
class MenuLevel(models.Model):
menu = models.ForeignKey(Menu, on_delete=models.CASCADE)
menu_item = models.ForeignKey(MenuItem, on_delete=models.CASCADE, related_name='items')
level = models.IntegerField(default=0)
parent = models.ForeignKey(MenuItem, on_delete=models.CASCADE, related_name='parent', null=True, blank=True)
I need the parent key to menu item to traverse through the menu items from parent to children and level to sort the menu in order.
On the admin I have two simple classes:
class MenuLevelInline(admin.TabularInline):
model = MenuLevel
#admin.register(Menu)
class MenuAdmin(admin.ModelAdmin):
inlines = [MenuLevelInline]
Here is the problem:
If I try to save two categories, one as a parent to another, things work fine. However, if I have a category as a parent and Page as a child I get IntegrityError: FOREIGN KEY constraint failed error.
When I look in the database, the menu_item table does contain all the keys for both Categories and pages table.
What did I do wrong?
Everything just worked once I switched to MySQL. It was not working on Sqlite. I don't know why it doesn't work with sqlite maybe it is a bug. But changing the database solved my problem.

How to fix manytomany field in django

How to make a one to many relationship in Django/Mysql?
I have an identical situation to this post, yet, my django returns errors on the admin page:
get() returned more than one order2pizza-- it returned 5!
order2pizza with that pizza already exists.
My mysql database have composite keys on a tertiary table to order and pizza to link multiple pizzas to an order.
models.py:
class Orders(models.Model):
order_id = models.AutoField(primary_key=True)
order_name = models.CharField(max_length=100, blank=True, null=True)
class Pizza(models.Model):
Pizza= models.AutoField(primary_key=True)
Pizza_name= models.CharField(max_length=50, blank=True, null=True)
class order2pizza(models.Model):
order = models.ManyToManyField(Orders, models.DO_NOTHING, )
pizza_id= models.IntegerField()
class Meta:
unique_together = (('order ', 'pizza_id'),)
A many-to-many relation can be expressed in two ways. First, you can manually specify a "join" model, like this:
class Orders(models.Model):
order_name = models.CharField(max_length=255, blank=True)
class Pizza(models.Model):
Pizza_name= models.CharField(max_length=255, blank=True)
class Order2Pizza(models.Model):
order = models.ForeignKey(Order, models.CASCADE)
pizza = models.ForeignKey(Pizza, models.CASCADE)
class Meta:
unique_together = ['order ', 'pizza']
This is useful if you want to put extra fields on the Order2Pizza model. A field named quantity would be very useful in your example.
The second option is to use a ManyToManyField. This will automatically create the join model for you:
class Orders(models.Model):
order_name = models.CharField(max_length=255, blank=True)
pizzas = models.ManyToManyField('Pizza', related_name='orders')
class Pizza(models.Model):
Pizza_name= models.CharField(max_length=255, blank=True)
In your original question you put the ManyToManyField on the Order2Pizza model, which is nonsensical.
However, the source of your bug is probably your manual inclusion of several *_id fields. Don't do that. They will always be created automatically by Django and you should never have to specify them manually. Instead, try the two options above and see how they work.

Add blog posts without category in django 1.11

I want to be able to add some blog posts with categories and some without categories in django. with this models django admin won't let me add blog posts without a category. Thanks.
from django.db import models
from django.db.models import permalink
class Blog(models.Model):
title = models.CharField(max_length=100, unique=True)
slug = models.SlugField(max_length=100, unique=True)
body = models.TextField()
pub_date = models.DateField(db_index=True, auto_now_add=True)
# Many-to-one relationship.
category = models.ForeignKey('blog.Category')
class Category(models.Model):
title = models.CharField(max_length=100)
slug = models.SlugField(max_length=100)
Update your model like this:
category = models.ForeignKey('blog.Category', blank=True, null=True)
blank=True allow forms to have a blank value.
null=True allows a null value in the database.
Edit: here is the documentation

Django unique together relationship with field and manytomany on self

I'm try create post with language and content, and relate it on other versions of same page, but I'm get stuck
class Page(models.Model):
content = models.TextField()
language = models.CharField(max_length=7, choices=settings.LANGUAGES)
versions = models.ManyToManyField('self', blank=True)
class Meta:
unique_together = ('language', 'versions',)
This will not work properly, because Django not allow make "unique" ManyToMany fields.
Then I'm try make same relationship trough related model:
class VersionsPage(models.Model):
pass
# ToDo: add unique together here, to foreign key field
class Page(models.Model):
...
versions = models.ManyToManyField('self', blank=True, through="VersionsPage")
Anyone know how to make that without using symmetrical=False?
I think you are looking for something like this:
class Page(models.Model):
pass
class PageVersion(models.Model):
page = models.ForeignKey(Page, related_name='versions')
content = models.TextField()
language = models.CharField(max_length=7, choices=settings.LANGUAGES)
class Meta:
unique_together = ('page', 'language',)
#getting all page versions:
page = Page.objects.get(pk=some_id)
versions = page.versions.all()

Query ManyToMany relations without a named through field

I have this setup in my models:
class Author(models.Model):
name = models.CharField(max_length=100)
class Topic(models.Model):
name = models.CharField(max_length=100)
class Article(models.Model):
name = models.CharField(max_length=100)
authors = models.ManyToManyField(Author, null=True, blank=True)
topics = models.ManyToManyField(Topic, null=True, blank=True)
Given an author, I want to know which topics he wrote about:
def author_info(request, pk):
author = get_object_or_404(Author, pk=pk)
topics = ????
If I had specified a through field, I could use that, but now Django makes the through field for me, and since its supposed to be transparent, Id rather not reference the field (unless there is a proper Django construction for that).
Use Lookups that span relationships:
topics = Topic.objects.filter(article__authors=author).distinct()
Note: you have to use distinct here, because the same topic can be selected by different articles.

Categories