I'm trying to implement a like system in Django, but I'm getting FOREIGN KEY constraint failed error
models.py
class Like(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="likes")
article = models.ForeignKey(Article, on_delete=models.CASCADE, related_name="likes")
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"{self.user.username} {self.article.Title}"
class Meta:
ordering = ('-created_at',)
views.py
def like(request, slug, pk):
if request.user.is_authenticated:
try:
like = Like.objects.get(article__slug=slug, user_id=request.user.id)
like.delete()
except:
Like.objects.create(article_id=pk, user_id=request.user.id)
return redirect('blog:article_detail', slug)
urls.py
path('like/<slug:slug>/<int:pk>', views.like, name='like_article')
Related
i'm building a small webstore , in the product page i put the order form using FormMixin and TemplateView, when i submit the order i get a "Direct assignment to the forward side of a many-to-many set is prohibited. Use product.set() instead." error
Bellow you can check the code
Models.py
from django.db import models
class Category(models.Model):
name = models.CharField(max_length=255, unique=True, )
description = models.TextField(max_length=1500)
class Meta:
verbose_name_plural = "categories"
def __str__(self):
return self.name
class Product(models.Model):
name = models.CharField(max_length=255)
description = models.TextField()
nominal_price = models.PositiveIntegerField(verbose_name='prix normal',)
reduced_price = models.PositiveIntegerField(blank=True, null=True)
quantity = models.PositiveIntegerField(default=10)
category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='products')
photo = models.ImageField(upload_to="img/products/", default="img/products/user_default.png")
def __str__(self):
return self.name
class Customer(models.Model):
full_name = models.CharField(max_length=150)
address = models.CharField(max_length=1500, null=True)
phone = models.IntegerField()
city = models.CharField(max_length=100)
email = models.EmailField(null=True)
class Order (models.Model):
product = models.ManyToManyField(Product, through='OrderProduct')
customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
class OrderProduct(models.Model):
order = models.ForeignKey(Order, on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
Views.py
class ProductDetailView(FormMixin, TemplateView):
model = Product
template_name = 'product.html'
form_class = OrderForm
def get_success_url(self):
return reverse('index')
def post(self, request, *args, **kwargs):
context = self.get_context_data()
form = OrderForm(request.POST)
if context['form'].is_valid():
product = get_object_or_404(Product, name=self.kwargs['product_name'])
customer = form.save()
Order.objects.create(product=product, customer=customer)
return super(TemplateView, self)
def get_context_data(self, **kwargs):
context = super(ProductDetailView, self).get_context_data(**kwargs)
context['product'] = Product.objects.get(name=self.kwargs['product_name'])
context['form'] = self.get_form()
return context
urls.py
path('', views.ProductListView.as_view(), name='index'),
Did i missed something
For handling many-to-many relations, you cannot directly set the product from Order. Also you would need to create the order first before you can set or add a product:
order = Order.objects.create(customer=customer)
order.product.add(product)
I would like to list out the comments on my Post Detail page and wanted to see how I can connect a view to the specific comments for a given post?
Models.py
class Post(models.Model):
owner = models.ForeignKey(
Profile, null=True, blank=True, on_delete=models.SET_NULL)
title = models.CharField(max_length=200)
body = models.TextField()
Post_image = models.ImageField(
null=True, blank=True, default='default.jpeg')
create_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post', kwargs={'pk': self.pk})
class Meta:
ordering = ['-create_date']
class Comment(models.Model):
owner = models.ForeignKey(Profile, on_delete=models.CASCADE, null=True)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
text = models.TextField()
create_date = models.DateTimeField(auto_now_add=True)
Views.py
class PostDetailView(DetailView):
model = Post
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['comment_list'] = Post.comment_set.all()
return context
You can access the detail object of the DetailView with self.object:
class PostDetailView(DetailView):
model = Post
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['comment_list'] = self.object.comment_set.order_by('create_date')
return context
I am getting the Value Error: Cannot query "post": Must be "UserProfile" instance when I make a get request to call PostListView.as_view().
Here is my model.py :
from django.db import models
from django.contrib.auth.models import User
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
username = models.CharField(max_length=30)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
email = models.EmailField()
password = models.CharField(max_length=100)
def __str__(self):
return self.user.username
class Post(models.Model):
user = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
title = models.CharField(max_length=100)
text = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
views.py :
class PostListView(ListAPIView):
serializer_class = PostSerializer
permission_classes = [AllowAny]
def get_queryset(self):
"""Returns only the object related to current user"""
user = self.request.user
return Post.objects.filter(user=user)
Also, I want a Foreign key relationship exists between User and Post on Model-level, not on the Database level.
user is UserProfile instance but request.user is a User instance
change this line like that to refernece to userprofile
user = self.request.user.userprofile
I have a model Offlinecheckout and CartItem model. I want to add a filter queryset of the cart field in the offline checkout model. As It is showing the cart of all users. I want to filter queryset by request.user.So that cart filed will show in the cart request.user only not other users.
How I can add a filter in that field.
Models.py
class OfflineCheckOut(models.Model):
user = models.ForeignKey('accounts.User', on_delete=models.CASCADE)
cart = models.ManyToManyField('cart.CartItem')
time_slot = models.ForeignKey('category.TimeSlot', on_delete=models.CASCADE)
state = models.CharField(max_length=254)
city = models.CharField(max_length=254)
address = models.CharField(max_length=254)
landmark = models.CharField(max_length=254, blank=True)
# order_id = models.ForeignKey('cart.CartModel', on_delete=models.CASCADE)
date = models.DateField()
tsn_amount = models.IntegerField()
def __str__(self):
return self.user.username
class CartItem(models.Model):
cart = models.ForeignKey('CartModel', on_delete=models.CASCADE)
user = models.ForeignKey('accounts.User', on_delete=models.CASCADE)
service = models.ForeignKey('accounts.SubCategory', on_delete=models.CASCADE)
defects = models.ForeignKey('category.Defects', on_delete=models.CASCADE)
quantity = models.IntegerField(default=1)
price = models.IntegerField()
created_on = models.DateTimeField(auto_now_add=True)
updated_on = models.DateTimeField(auto_now_add=True)
serializers.py
from rest_framework import serializers
from .models import Address, Date, OfflineCheckOut
class OfflineSerializer(serializers.ModelSerializer):
class Meta:
model = OfflineCheckOut
fields = "__all__"
views.py
class offlineViewSet(viewsets.ModelViewSet):
permission_classes = (IsAuthenticated,)
def get_queryset(self):
user = self.request.user
if user.is_authenticated:
if user is not None:
if user.is_active and user.is_superuser or user.is_Customer:
return OfflineCheckOut.objects.all()
raise PermissionDenied()
raise PermissionDenied()
raise PermissionDenied()
serializer_class = OfflineSerializer
You can filter relations by using FilteredRelation in Django
Please change your views.py as follow
from django.db.models import FilteredRelation, Q
class offlineViewSet(viewsets.ModelViewSet):
permission_classes = (IsAuthenticated,)
def get_queryset(self):
user = self.request.user
if user.is_authenticated:
if user is not None:
if user.is_active and user.is_superuser or user.is_Customer:
### Use filtered relation
return OfflineCheckOut.objects.filter(user=user).annotate(user_cart=FilteredRelation('cart', condition=Q(cart__user=user)))
raise PermissionDenied()
raise PermissionDenied()
raise PermissionDenied()
serializer_class = OfflineSerializer
I hope this will help you to resolve an issue.
Please refer FilteredRelation objects for more information.
If you require further help please comment
I am trying to create a django application to keep track of a product(product stock application).whenever I try to add new product ,I cannot add more than one product in the same category. It gives UNIQUE constraint failed error .
I want to add multiple products in same category.
models.py
from django.db import models
class Category(models.Model):
name = models.CharField(max_length=100, blank=True, null=True)
def __str__(self):
return self.name
class Product(models.Model):
name = models.CharField(max_length=100)
slug = models.CharField(max_length=100)
price = models.DecimalField(max_digits=6, decimal_places=2)
quantity = models.IntegerField(null=True, blank=True)
category = models.ForeignKey(
Category, on_delete=models.CASCADE)
def __str__(self):
return self.name
class Stock(models.Model):
sold_quantity = models.IntegerField(null=True, blank=True)
product = models.ForeignKey(Product, on_delete=models.CASCADE, null=True)
def __str__(self):
return self.product.name
Edit:
Views
def createProduct(request):
form = AddProductForm()
if request.method == 'POST':
form = AddProductForm(request.POST)
if form.is_valid():
form.save()
return redirect('/')
contex = {'form': form}
return render(request, 'stockmgmt/add_products.html', contex)
Forms.py
class AddProductForm(ModelForm):
class Meta:
model = Product
fields = '__all__'
Error Message