Update Django Model With Form Field - python

I am trying to update the quantity of my Inventory model using a Integer form field on the front end. I am able to add a new inventory item, but I want to update existing items. Here is my code:
FROM VIEWS.PY
def view_inventory(request, slug):
if request.method == 'POST':
quantity_add = addQuantity(request.POST)
if quantity_add.is_valid():
cd = quantity_add.cleaned_data
addq=Inventory(quantity = cd.get('quantity'))
addq.save()
quantity_add=addQuantity()
return render(request, 'inv/view_inventory.html', {
'item': get_object_or_404(Inventory.objects.all(), slug=slug),
'form' : quantity_add,
})
FROM MODELS.PY
class Inventory(models.Model):
quantity = models.IntegerField()
name = models.CharField(max_length=150, unique = True)
slug = models.SlugField(unique = True)
date = models.DateTimeField(auto_now_add=True)
description = models.CharField(max_length=250)
category = models.ForeignKey(Category, null=True, blank=True)
def __unicode__(self):
return self.name
#permalink
def get_absolute_url(self):
return ('view_inventory', None, { 'slug' : self.slug })
class Meta:
ordering = ['-date']
FROM URLS.PY
url(r'^(?P<slug>[\w\-]+)/$', 'inv.views.view_inventory', name='view_inventory'),

You only have to get the record and then update it:
def view_inventory(request, slug):
if request.method == 'POST':
quantity_add = addQuantity(request.POST)
if quantity_add.is_valid():
cd = quantity_add.cleaned_data
old_inventory = Inventory.objects.get(id=something here) #id or pk or whatever you want
old_inventory.quantity = cd.get('quantity')
old_inventory.save()
quantity_add=addQuantity()
return render(request, 'inv/view_inventory.html', {
'item': get_object_or_404(Inventory.objects.all(), slug=slug),
'form' : quantity_add,
})

Related

Why is adding styling or widgets to Django forms will prevent data from being saved in database?

I just tried multiple ways of styling my Django form but every time I did it prevents data from being saved in Django's admin database.
Here is my code :
models.py :
class listing(models.Model):
title = models.CharField(max_length=64)
describtion = models.CharField(max_length=300)
bid = models.FloatField()
category = models.ForeignKey(categories, default=1, verbose_name="Category", on_delete=models.SET_DEFAULT)
user = models.ForeignKey(User,default='', verbose_name="User", on_delete=models.SET_DEFAULT)
image = models.CharField(max_length=400)
def __str__(self):
return f"{self.title} "
class create(ModelForm):
class Meta:
model = listing
fields = [ 'title', 'describtion','bid','category','image']
After adding widgets :
class create(ModelForm):
class Meta:
model = listing
fields = [ 'title', 'describtion','bid','category','image']
widgets={
'title': TextInput(attrs={'class':'form-control'}),
'describtion': TextInput(attrs={'class':'form-control'}),
'image': TextInput(attrs={'class':'form-control'}),
'bid': NumberInput(attrs={'class':'form-control'}),
'category': SelectMultiple(attrs={'class':'form-control'}),
}
Views.py:
def CreateListing(request):
user = request.user
if request.method == "POST":
form = create(request.POST, request.FILES)
if form.is_valid():
form.instance.user = user
form.save()
return redirect('listing')
else:
return render(request, "auctions/Create.html",{
'form': create
})
Ps : without widgets, data will be saved in the Database.

Django extending the User model in ECommerce application

I have a django ecommerce project that works fine till I decided to improve it. User place order and every time they place an order they have to always input their details (name, emil, address etc) , I decided to upgrade the application so if user had registered before no need to enter details again .
orders/models.py
from django.db import models
from django.contrib.auth.models import User
from shop.models import Product
from decimal import Decimal
from django.core.validators import MinValueValidator,MaxValueValidator
from coupons.models import Coupons
class order(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
email = models.EmailField()
address = models.CharField(max_length=250)
postal_code = models.CharField(max_length=50)
city = models.CharField(max_length=100)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
paid = models.BooleanField(default=False)
coupon = models.ForeignKey(Coupons,related_name='orders',on_delete=models.CASCADE ,null=True,blank=True)
discount = models.IntegerField(default=0,validators=[MinValueValidator(0),MaxValueValidator(100)])
class Meta:
ordering = ('-created',)
verbose_name = "order"
verbose_name_plural = "orders"
def __str__(self):
return 'Order {}'.format(self.id)
def get_total_cost(self):
return sum(item.get_cost() for item in self.items.all())
def get_total_cost_after_discount(self):
total_cost = sum(item.get_cost() for item in self.items.all())
return total_cost - total_cost * (self.discount / Decimal('100'))
class OrderItem(models.Model):
order = models.ForeignKey(order,related_name='items',on_delete=models.CASCADE)
product = models.ForeignKey(Product,related_name='order_items',on_delete=models.CASCADE)
price = models.DecimalField(max_digits=10,decimal_places=2)
quantity = models.PositiveIntegerField(default=1)
class Meta:
verbose_name = "OrderItem"
verbose_name_plural = "OrderItems"
def __str__(self):
return '{}'.format(self.id)
def get_cost(self):
return self.price * self.quantity
I create account app and extended django user so that user can register address so that the user does not have to type it every time when place an order.
accounts/models.py
class UserProfile(models.Model):
user = models.OneToOneField(User,related_name='UserProfiles',on_delete=models.CASCADE)
country = models.CharField(max_length=300, default='Saudi Arabia')
city = models.CharField(max_length=100, default='')
phone = models.CharField(max_length=15,default='')
image = models.ImageField(upload_to='profile_image', blank=True)
created_date = models.DateTimeField(auto_now_add=True)
updated_date = models.DateTimeField(null=True)
def __str__(self):
return self.user.username
def create_profile(sender, **kwargs):
if kwargs['created']:
user_profile = UserProfile.objects.create(user=kwargs['instance'])
post_save.connect(create_profile, sender=User)
and rewrite:
orders/models.py
class order(models.Model):
user = models.ForeignKey(User,on_delete=models.DO_NOTHING)
address = models.ForeignKey(UserProfile,on_delete=models.DO_NOTHING)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
paid = models.BooleanField(default=False)
coupon = models.ForeignKey(Coupons,related_name='orders',on_delete=models.CASCADE ,null=True,blank=True)
discount = models.IntegerField(default=0,validators=[MinValueValidator(0),MaxValueValidator(100)])
now my problem is how can I fix the view to show form of user address with information if user entered before or the user fill form with address
views.py
#login_required
def order_create(request):
cart = Cart(request)
if request.method == 'POST':
form = OrderCreateForm(request.POST)
if form.is_valid():
order = form.save(commit=False)
if cart.coupon:
order.coupon = cart.coupon
order.discount = cart.coupon.discount
order.save()
for item in cart:
OrderItem.objects.create(
# user = User.username,
order=order,
product=item['product'],
price=item['price'],
quantity=item['quantity'])
cart.clear()
context = {
'order':order,
}
return render(request, 'created.html',context)
else:
form = OrderCreateForm()
context = {
'cart':cart,
'form':form
}
return render(request, 'create.html',context)
orders/forms.py
from django import forms
from .models import order
class OrderCreateForm(forms.ModelForm):
class Meta:
model = order
fields = ('first_name','last_name','email','address','postal_code','city',)
I don't see your OrderCreateForm, but I'm assuming it has fields that match the ones in UserProfile. If so, try changing the view code to pull data from the profile to populate the initial data:
#login_required
def order_create(request):
cart = Cart(request)
if request.method == 'POST':
form = OrderCreateForm(request.POST)
if form.is_valid():
order = form.save(commit=False)
if cart.coupon:
order.coupon = cart.coupon
order.discount = cart.coupon.discount
order.save()
for item in cart:
OrderItem.objects.create(
# user = User.username,
order=order,
product=item['product'],
price=item['price'],
quantity=item['quantity'])
cart.clear()
context = {
'order':order,
}
return render(request, 'created.html',context)
else:
if request.user and hasattr(request.user, 'UserProfiles'):
profile = request.user.UserProfiles
initial = {
'first_name', request.user.first_name,
'last_name', request.user.last_name,
'email', request.user.email,
'address': profile.address,
'city': profile.city
}
else:
initial = {}
form = OrderCreateForm(initial=initial)
context = {
'cart':cart,
'form':form
}
return render(request, 'create.html',context)

How to create a like functionality in django for a blog

I have to build a blog for my chess club and I would like to make a like functionality for the posts. When the user likes the post the like count increases and the post its shown in the user profile.
Here is what I made so far:
This is my post model:
class Post(models.Model):
title = models.CharField(max_length=100)
overview = models.TextField()
timestamp = models.DateTimeField(auto_now_add=True)
content = HTMLField()
is_aproved = models.BooleanField(default=False)
# comment_count = models.IntegerField(default = 0)
# view_count = models.IntegerField(default = 0)
slug = models.SlugField(unique=True, blank=True)
likes = models.ManyToManyField(
settings.AUTH_USER_MODEL, blank=True, related_name='post_likes')
author = models.ForeignKey(Author, on_delete=models.CASCADE)
thumbnail = models.ImageField()
categories = models.ManyToManyField(Category)
featured = models.BooleanField()
previous_post = models.ForeignKey(
'self', related_name='previous', on_delete=models.SET_NULL, blank=True, null=True)
next_post = models.ForeignKey(
'self', related_name='next', on_delete=models.SET_NULL, blank=True, null=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post-detail', kwargs={
'id': self.id
})
def get_update_url(self):
return reverse('post-update', kwargs={
'id': self.id
})
def get_delete_url(self):
return reverse('post-delete', kwargs={
'id': self.id
})
#property
def get_comments(self):
return self.comments.all().order_by('-timestamp')
#property
def comment_count(self):
return Comment.objects.filter(post=self).count()
#property
def view_count(self):
return PostView.objects.filter(post=self).count()
And this is my view:
def post(request, id):
category_count = get_category_count()
most_recent = Post.objects.order_by('-timestamp')[:3]
post = get_object_or_404(Post, id=id)
if request.user.is_authenticated:
PostView.objects.get_or_create(user=request.user, post=post)
form = CommentForm(request.POST or None)
if request.method == "POST":
if form.is_valid():
form.instance.user = request.user
form.instance.post = post
form.save()
return redirect(reverse("post-detail", kwargs={
'id': post.pk
}))
context = {
'form': form,
'post': post,
'most_recent': most_recent,
'category_count': category_count,
'form': form
}
return render(request, 'post.html', context)
could you help me to implement this like functionality
You need another model to get liking functionality in Django. Create a like model like this-
class PostLikes(models.Model):
user = models.ForeignKey(User)
post = models.ForeignKey(Post)
created = models.DateTimeField(auto_now_add=True)
then create a view to add the instance to the PostLikes model-
def like_others_post(request, post_id):
new_like, created = PostLikes.objects.get_or_create(user=request.user,
post_id=post_id)
if not created:
# you may get and delete the object as the user may already liked this
post before
We are using get or create to avoid duplication of likes. So a user may click multiple times but, a like instance is stored only once.
then add a method to Post model for getting the number of likes-
def Post(models.Model):
...
...
#property
def view_count(self):
return PostLikes.objects.filter(post=self).count()
To find out if the current user already likes the displayed post or not, in your post view-
def post(request, id):
....
....
already_liked = PostLikes.objects.filter(user=request.user, post=post).count()
if number_of_likes > 0:
already_liked = True # pass this variable to your context
else:
already_liked = False # you can make this anything other than boolean
Then by use of Javascript and {{already_liked}}, change your animation of like button in your template.

Django: How to filter ForeignKey choices by request.user with ModelFormSet

I just want to filter select field in a form, regarding a currently logged user. Every user has own categories and budgets - I want to display only a models related with a currently logged user. I've tried stuff with filtering before is_valid field, but with no result. Please, find my code below:
views.py
#login_required
def day_data_multiadd(request, no_of_lines=0):
no_of_lines = int(no_of_lines)
CostFormSet = modelformset_factory(Cost, form=DataAddForm, extra=no_of_lines)
if request.method == 'POST' and 'form' in request.POST:
formset = CostFormSet(request.POST, request.FILES)
if formset.is_valid():
for form in formset.forms:
f = form.save(commit=False)
f.user = request.user
f.save()
else:
formset = CostFormSet(queryset=Cost.objects.none())
if request.method == 'POST' and 'no_line' in request.POST:
generate_form = MultiaddGenerateForm(request.POST)
if generate_form.is_valid():
cd = generate_form.cleaned_data
return HttpResponseRedirect(reverse('core_sm:day_data_multiadd', args=(cd['formy'], )))
else:
generate_form = MultiaddGenerateForm()
return render(request, 'core_sm/costs/multi_add.html', {'formset': formset,
'no_of_lines': no_of_lines,
'generate_form': generate_form})
forms.py
class DataAddForm(forms.ModelForm):
class Meta:
model = Cost
fields = ['title', 'value', 'publish', 'category', 'budget']
exclude = ['user']
labels = {
'title': _('Tytuł'),
'value': _('Wartość'),
'publish': _('Data'),
'category': _('Kategoria'),
'budget': _('Budżet')
}
models.py
class Category(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL)
title = models.CharField(max_length=200)
publish = models.DateField(auto_now_add=True)
updated = models.DateField(auto_now=True)
class Meta:
ordering = ('-publish',)
def __str__(self):
return self.title
def get_absolute_ur(self):
return reverse('core_sm:category_detail', args=[self.id])
class Budget(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL)
title = models.CharField(max_length=200, db_index=True)
value = models.DecimalField(decimal_places=2, max_digits=10)
publish = models.DateField(auto_now_add=True)
updated = models.DateField(auto_now=True)
class Meta:
ordering = ('-publish',)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('core_sm:budget_detail', args=[self.id])
class Cost(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL)
budget = models.ForeignKey(Budget, related_name='cost')
category = models.ForeignKey(Category, related_name='cost')
title = models.CharField(max_length=200, db_index=True)
publish = models.DateField(default=timezone.now)
created = models.DateField(auto_now_add=True)
updated = models.DateField(auto_now=True)
value = models.DecimalField(max_digits=10, decimal_places=2)
class Meta:
ordering = ('-publish',)
def get_absolute_url(self):
return reverse('core_sm:stats_detail', args=[self.publish.year,
self.publish.strftime('%y'),
self.publish.strftime('%m'),
self.publish.strftime('%d')])
def __str__(self):
return self.title
According to the docs you can pass custom parameters to formsets forms.
class DataAddForm(forms.ModelForm):
class Meta:
model = Cost
fields = ['title', 'value', 'publish', 'category', 'budget']
exclude = ['user']
labels = {
'title': _('Tytuł'),
'value': _('Wartość'),
'publish': _('Data'),
'category': _('Kategoria'),
'budget': _('Budżet')
}
def __init__(self, *args, **kwargs):
user = kwargs.pop('user')
self.fields['category'].queryset = Category.objects.filter(user=user)
self.fields['budget'].queryset = Budget.objects.filter(user=user)
super(DataAddForm, self).__init__(*args, **kwargs)
views.py
formset = CostFormSet(queryset=Cost.objects.none(), form_kwargs={'user': request.user})

django python slug variable in models.py

While I hit the search button..it shows the
Page not found (404)
No Category matches the given query.
My views
def search_in_category(request, slug):
# reset the search params, if present
try:
del request.session['search']
except KeyError:
pass
return search_results(request, slug)
def search_results(request, slug):
category = get_object_or_404(Category, slug=slug)
fields = list(category.field_set.all())
fields += list(Field.objects.filter(category=None))
fieldsLeft = [field.name for field in fields]
if request.method == "POST" or 'search' in request.session:
ads = category.ad_set.filter(active=True,
expires_on__gt=datetime.datetime.now())
# A request dictionary with keys defined for all
# fields in the category.
post = {}
if 'search' in request.session:
post.update(request.session['search'])
else:
post.update(request.POST)
sforms = prepare_sforms(fields, fieldsLeft, post)
isValid = True
for f in sforms:
# TODO: this assumes the form is not required
# (it's a search form after all)
if not f.is_valid() and not f.is_empty():
isValid = False
if isValid:
if request.method == 'POST':
request.session['search'] = {}
request.session['search'].update(request.POST)
return redirect('classifieds_browse_search_results', slug=slug)
for f in sforms:
ads = f.filter(ads)
if ads.count() == 0:
return render_to_response('classifieds/list.html',
{'no_results': True,
'category': category},
context_instance=RequestContext(request))
else:
context = context_sortable(request, ads)
context['category'] = category
return render_to_response('classifieds/list.html', context,
context_instance=RequestContext(request))
else:
sforms = prepare_sforms(fields, fieldsLeft)
return render_to_response('classifieds/search.html',
{'forms': sforms, 'category': category},
context_instance=RequestContext(request))
My models.py
class Category(models.Model):
site = models.ForeignKey(Site)
template_prefix = models.CharField(max_length=200, blank=True)
name = models.CharField(max_length=200)
slug = models.SlugField()
enable_contact_form_upload = models.BooleanField(default=False)
contact_form_upload_max_size = models.IntegerField(default=2 ** 20)
contact_form_upload_file_extensions = models.CharField(max_length=200,
default="txt,doc,odf,pdf")
images_max_count = models.IntegerField(default=0)
images_max_width = models.IntegerField(help_text=_(u'Maximum width in pixels.'),
default=1024)
images_max_height = models.IntegerField(help_text=_(u'Maximum height in pixels.'),
default=1024)
images_max_size = models.IntegerField(help_text=_(u'Maximum size in bytes.'),
default=2 ** 20)
images_allowed_formats = models.ManyToManyField(ImageFormat, blank=True)
description = models.TextField(default='')
sortby_fields = models.CharField(max_length=200,
help_text=_(u'A comma separated list of field names that should show up as sorting options.'),
blank=True)
sort_order = models.PositiveIntegerField(default=0)
def __unicode__(self):
return self.name + u' Category'
class Meta:
verbose_name_plural = u'categories'
My url
url(r'^search/(?P<slug>[-\w]+)/$', 'browse.search_in_category',
name='classifieds_browse_category_search'),
url(r'^search/results/(?P<slug>[-\w]+)/$', 'browse.search_results',
name='classifieds_browse_search_results'),
This my code, Why I am getting the 404 error? What I have to do for fix this error?
you cannot do
return search_results(request, slug)
do rather this redirect
return redirect(reverse('classifieds_browse_search_results', kwargs={'slug':slug}))
dont forget to import
from django.core.urlresolvers import reverse
from django.shortcuts import redirect

Categories

Resources