How to use two model forms on one view - python

I'm still new to django, I'm working on a project where I'll need users to enter some information about houses they want to rent out. I want the users to upload a minimum of 6 pictures and from what I've gathered, the best way to do this on django is to use two models, one collects basic information about the houses and the second stores images of the houses. How am I supposed to code the views.py. I've tried all to no avail.
forms.py
class MyHouseEditForm(forms.ModelForm):
class Meta:
model = Myhouses
fields = ('name_of_accomodation',
'type_of_apartment','Number_of_rooms', 'house_rent',
'availability', 'location', 'nearest_institution',
'description',)
class ImageForm(forms.ModelForm):
class Meta:
model = Image
fields = ('__all__' )
models.py
class Myhouses(models.Model):
Available = 'A'
Not_Available = 'NA'
Availability = (
(Available, 'Available'),
(Not_Available, 'Not_Available'),
)
Flat = 'F'
Self_contained = 's'
Bungalow = 'b'
Mini_flat = 's'
Duplex = 'D'
Room = (
(Flat, 'Flat'),
(Self_contained, 'Self_contained'),
(Bungalow, 'Bungalow'),
(Mini_flat, 'Mini_flat'),
(Duplex, 'Duplex'),
)
time = models.DateTimeField(default = datetime.now, blank = True)
name_of_accomodation = models.CharField(max_length=20)
type_of_apartment = models.CharField(max_length=2, choices=Room, )
Number_of_rooms = house_rent = models.IntegerField()
house_rent = models.IntegerField()
availability = models.CharField(max_length=2, choices=Availability, default=Available,)
location = models.CharField(max_length=200)
nearest_institution = models.CharField(max_length=200)
description = models.TextField(blank=True)
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True, related_name='author')
def __str__(self):
return self.name_of_accomodation
def get_absolute_url(self):
return reverse('search-detail', args=[str(self.id)])
class Meta:
ordering = ["-time"]
class Image(models.Model):
myhouses = models.ForeignKey(Myhouses, related_name='images', on_delete=models.PROTECT)
image = models.ImageField(upload_to='documents/')
views.py
def addlisting(request):
if request.method == 'POST':
Hform = MyHouseEditForm(request.POST, files=request.FILES, )
Iform = ImageForm(request.POST, request.FILES, )
if Hform.is_valid() and Iform.is_valid():
Houses = Hform.save(commit=False)
Houses.author=request.user
Houses.save()
image = iform.save(commit=False)
Houses.image.myhouses = myhouses
Houses.save()
messages.success(request, 'Listing Created Succesfully successfully')
return redirect('addlisting')
else:
Hform = MyHouseEditForm()
Iform = ImageForm()
return render(request, 'houses/addlisting.html', {'Hform':Hform, 'Iform': Iform}, )

Related

Not able to Update CRUD data with foreign keys despite putting correct namings

I am doing CRUD data which has foreign keys and serializers(since I am told to use serializers instead of Forms),even though I have put the correct model and it's names in the product_edit page, the data is showing blank instead of thier saved data ,the wrong sub_category name is coming,this is how the edit page currently looks
serializer:
class CategoriesSerializer(serializers.ModelSerializer):
class Meta:
model = Categories
fields = "__all__"
extra_kwargs = {'category_name': {'required': False}}
class ColorsSerializer(serializers.ModelSerializer):
class Meta:
model = Colors
fields = "__all__"
class POLLSerializer(serializers.ModelSerializer):
# categories = serializers.StringRelatedField(many=False)
# sub_categories = serializers.StringRelatedField(many=False)
# color = serializers.StringRelatedField(many=False)
# size = serializers.StringRelatedField(many=False)
class Meta:
model = Products
fields = "__all__"
class SizeSerializer(serializers.ModelSerializer):
class Meta:
model = Size
fields = "__all__"
class SUBCategoriesSerializer(serializers.ModelSerializer):
class Meta:
model = SUBCategories
fields = "__all__"
below are the models of my CRUD
class Products(models.Model):
categories = models.ForeignKey(Categories,on_delete=models.CASCADE)
sub_categories = models.ForeignKey(SUBCategories,on_delete=models.CASCADE)
color = models.ForeignKey(Colors,on_delete=models.CASCADE)
size = models.ForeignKey(Size,on_delete=models.CASCADE)
# image = models.ImageField(upload_to = 'media/',width_field=None,height_field=None,null=True)
title = models.CharField(max_length=50)
price = models.CharField(max_length=10)
sku_number = models.CharField(max_length=10)
product_details = models.CharField(max_length=300)
quantity = models.IntegerField(default=0)
isactive = models.BooleanField(default=True)
class Categories(models.Model):
#made changes to category_name for null and blank
category_name = models.CharField(max_length=20)
category_description = models.CharField(max_length=20)
isactive = models.BooleanField(default=True)
def __str__(self):
return self.category_name
class Colors(models.Model):
color_name = models.CharField(max_length=10)
color_description = models.CharField(max_length=10)
isactive = models.BooleanField(default=True)
def __str__(self):
return self.color_name
class Size(models.Model):
size_name = models.CharField(max_length=10)
size_description = models.CharField(max_length=20)
isactive = models.BooleanField(default=True)
def __str__(self):
return self.size_name
class SUBCategories(models.Model):
category_name = models.ForeignKey(Categories, on_delete=models.CASCADE)
sub_categories_name = models.CharField(max_length=20)
sub_categories_description = models.CharField(max_length=20)
isactive = models.BooleanField(default=True)
def __str__(self):
return self.sub_categories_name
update function
def update(request,id):
if request.method == 'GET':
print('GET',id)
edit_products = SUBCategories.objects.filter(id=id).first()
s= SUBCategoriesSerializer(edit_products)
category_dict = Categories.objects.filter(isactive=True)
category = CategoriesSerializer(category_dict, many=True)
sub_category_dict = SUBCategories.objects.filter(isactive=True)
sub_category = SUBCategoriesSerializer(sub_category_dict,many=True)
color_dict = Colors.objects.filter(isactive=True)
color = ColorsSerializer(color_dict,many=True)
size_dict = Size.objects.filter(isactive=True)
size = SizeSerializer(size_dict,many=True)
hm = {"context": category.data,"sub_context":sub_category.data,"color_context":color.data,"size_context":size.data,"SUBCategories":s.data}
return render(request,'polls/product_edit.html',hm)
else:
print('POST',id)
editproducts = {}
d = Products.objects.filter(id=id).first()
if d:
editproducts['categories']=request.POST.get('categories')
editproducts['sub_categories']=request.POST.get('sub_categories')
editproducts['color']=request.POST.get('color')
editproducts['size']=request.POST.get('size')
editproducts['title']=request.POST.get('title')
editproducts['price']=request.POST.get('price')
editproducts['sku_number']=request.POST.get('sku_number')
editproducts['product_details']=request.POST.get('product_details')
# print(editsubcategories)
form = SUBCategoriesSerializer(d,data= editproducts)
if form.is_valid():
form.save()
print("form data",form.data)
print('form error',form.errors)
messages.success(request,'Record Updated Successfully...!:)')
return redirect('polls:show')
else:
print(form.errors)
return redirect("polls:show")
where am I going wrong in the code?
you must create product serializer like below
class ProductSerial(ModelSerializer):
class Meta:
model = Products
fields = '__all__'
and pass editproducts to this serializer
and also you have to be careful that pass id's of
categories
sub_categories
color
size
into request.POST data

Displaying choice from a Model form based on another model

Working on a project that I am stumped on and I can't seem to find a good solution to this. An overview of the problem I need to resolve. I have 3 models (Games, GameRoles, and Groups) I have a defined list of games and a user can create a group from that list. The games also have roles associated with them. So the idea is I want a user to create a group based on a game from my game model, each game has different roles associated with it. When the user creates a group I want those roles to display in a checkbox field so they can add these roles if they need them.
My problem is I can't seem to find a good way to do this. I read the docs and I think what I need is an Iterating relationship choice class in my forms.py
Games model.py
from django.db import models
from django.db.models.aggregates import Max
from django.db.models.fields.related import ForeignKey
# Create your models here.
class Game(models.Model) :
GENRE_CHOICES = [
('Action', 'Action'),
('Acion-Adventure', 'Action-Adventure'),
('Adventure', 'Adventure'),
('MMO', 'MMO'),
('Puzzle', 'Puzzle'),
('Role Playing', 'Role Playing'),
('Simulation', 'Simulation'),
('Strategy', 'Strategy'),
('Sports', 'Sports')
]
RATING_CHOICES = [
('E', 'Everyone'),
('E10+', 'Everyone 10+'),
('T', 'Teen'),
('M', 'Mature 17+'),
('A', 'Adults Only 18+'),
('RP', 'Rating Pending')
]
PLATFORM_CHOICES = [
('Multi', 'Multi Platform'),
('PC', 'PC'),
('XBOX', 'XBOX'),
('Playstation', 'Playstation'),
('Nintendo', 'Nintendo')
]
name = models.CharField(max_length=200)
platform = models.CharField(max_length=20,
null=True,
choices=PLATFORM_CHOICES,
default='Select'
)
publisher = models.CharField(max_length=100)
genre = models.CharField(max_length=100,
null=True,
choices=GENRE_CHOICES,
default='Select'
)
rating = models.CharField(max_length=15,
null=True,
choices=RATING_CHOICES,
default='Select'
)
release_date = models.DateField()
tags = models.CharField(max_length=200)
picture = models.ImageField(
max_length=200,
default='games/default.png',
null=True,
upload_to='games/'
)
is_new = models.BooleanField(null=True)
is_popular = models.BooleanField(null=True)
is_featured = models.BooleanField(null=True)
def __str__(self):
return self.name
class GameRole(models.Model):
game = models.ForeignKey(Game, on_delete=models.CASCADE)
role = models.CharField(max_length=200)
def __str__(self):
return self.role
Group models.py
from django.contrib.auth.models import User
from django.db import models
from django.db.models.aggregates import Max
from games.models import Game, GameRole
# Create your models here.
class Group(models.Model):
name = models.CharField(max_length=200)
game = models.ForeignKey(Game, on_delete=models.CASCADE)
size = models.IntegerField(default=1)
total_size = models.IntegerField(null=True)
play_time = models.DateTimeField(null=True)
description = models.TextField(max_length=200)
is_full = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
discord = models.URLField(max_length=200, null=True)
user = models.ForeignKey(User, null=True, on_delete=models.CASCADE)
def __str__(self):
return self.name
class GroupRole(models.Model):
group = models.ForeignKey(Group, on_delete=models.CASCADE)
role = models.ForeignKey(GameRole, on_delete=models.CASCADE)
def __str__(self):
return self.role
forms.py
from django import forms
from django.contrib.auth.models import User
from django.forms import fields, widgets
from LFG.models import Group, GroupMembers, GroupRole
from games.models import Game, GameRole
class DateTimeInput(forms.DateTimeInput):
input_type = 'datetime-local'
class CheckboxInput(forms.CheckboxInput):
input_type = 'checkbox'
class RoleSelect(form.Select):
def creation_option(self, name, value, label, selected, index, subindex=None, attrs=None):
option = super().create_option(name, value, label, selected, index, subindex, attrs)
class GroupForm(forms.ModelForm):
game = forms.ModelChoiceField(queryset=Game.objects.all())
class Meta():
model = Group
fields = ['game', 'name']
class GroupTwoForm(forms.ModelForm):
ROLE_CHOICES = []
roles= forms.ModelMultipleChoiceField(ROLE_CHOICES)
class Meta():
model = Group
fields = ['name', 'total_size', 'play_time', 'description', 'discord']
widgets = {
'play_time':DateTimeInput(),
#'roles':CheckboxInput()
}
def role_display(game_id):
roles = GameRole.object.all()
for role in roles:
if role.game_id == game_id:
r = role
ROLE_CHOICES[r] = r
return ROLE_CHOICES
class GroupMemberForm(forms.ModelForm):
class Meta():
model = GroupMembers
fields = [ 'group', 'member', 'role']
views.py
#login_required(login_url='/login')
def create_group_2_view(request, group_id):
profile = request.user.userprofile
form_user = Group.objects.filter(pk=group_id).values('user')
formID = Group.objects.filter(pk=group_id).first()
roles = GameRole.objects.all()
print(form_user)
if request.method == 'POST':
form = GroupTwoForm(request.POST or None, instance=formID)
# if group_id == form.pk:
if form.is_valid():
form.save()
messages.success(request, 'Group created!')
return redirect('lfg')
else:
print(form.errors)
messages.error(request, form.errors)
return redirect('create-group-2', formID)
else:
form = GroupTwoForm(instance=formID)
context = {
'title':'Create a Group',
'year':datetime.now().year,
'profile':profile,
'form':form,
'roles':roles,
}
return render(request, 'lfg/create-group-2.html', context)
As you can see in forms.py I was attempting to create a role section class that will do this and then pass it to GroupTwoForm. Sorry if this is a bit confusing, still learning Django, if clarification is needed I will clarify.

How to show child table in Django REST Framework API view

I'm using Django as Backend, PostgresSQl as DB and HTML, CSS and Javascript as Frontend. I want to show Children Table in DJANGO REST FRAMEWORK, as I'm using Multi Table Inheritance.
As we can see in above image, that only Product list is been displayed but not the children table. I want to show all the data which is selected by customer. I'm showing Cart Product in DRF
views.py
class AddToCartView(TemplateView):
template_name = "status.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
product_id = self.kwargs['pk']
product_obj = Product.objects.get(id = product_id)
cart_id = self.request.session.get("cart_id", None)
if cart_id:
cart_obj = Cart.objects.get(id = cart_id)
this_product_in_cart = cart_obj.cartproduct_set.filter(product = product_obj)
if this_product_in_cart.exists():
cartproduct = this_product_in_cart.last()
cartproduct.quantity += 1
cartproduct.subtotal += product_obj.price
cartproduct.save()
cart_obj.total += product_obj.price
cart_obj.save()
else:
cartproduct = CartProduct.objects.create(
cart = cart_obj, product = product_obj, rate = product_obj.price, quantity = 1, subtotal = product_obj.price)
cart_obj.total += product_obj.price
cart_obj.save()
else:
cart_obj = Cart.objects.create(total=0)
self.request.session['cart_id'] = cart_obj.id
cartproduct = CartProduct.objects.create(
cart = cart_obj, product = product_obj, rate = product_obj.price, quantity = 1, subtotal = product_obj.price)
cart_obj.total += product_obj.price
cart_obj.save()
return context
API View (views.py)
#api_view(['GET'])
def showproduct(request):
result = CartProduct.objects.all()
serialize = productserializers(result, many = True)
return Response(serialize.data)
models.py
class Product(models.Model):
name = models.CharField(max_length=1330)
image_src = models.URLField(max_length=1330,null=True, blank=True)
link_href = models.URLField(max_length=1330,null=True, blank=True)
brand = models.CharField(max_length = 1330, null=True, blank=True)
price = models.DecimalField(max_digits=15, decimal_places=2)
created = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ('-created',)
class Refrigerator(Product):
series = models.CharField(max_length = 300, null=True, blank=True)
model = models.CharField(max_length = 300, null=True, blank=True)
...
class Cart(models.Model):
customer = models.ForeignKey(Customer, on_delete=models.SET_NULL, null=True, blank=True)
total = models.PositiveIntegerField(default=0)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return "Cart: " + str(self.id)
class CartProduct(models.Model):
cart = models.ForeignKey(Cart, on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
rate = models.PositiveIntegerField()
quantity = models.PositiveIntegerField()
subtotal = models.PositiveIntegerField()
def __str__(self):
return "Cart: " + str(self.cart.id) + " CartProduct: " + str(self.id)
I want to show refrigerator details aslo in DRF which is been selected by customer.
serializer.py
class productserializers(serializers.ModelSerializer):
class Meta:
model = CartProduct
fields = "__all__"
depth = 2
You can try this, in your Product(models.Model)
class Meta:
abstract = True
you can refer here for explanation : here
(I should have comment this but don't have enough reputations for that :/)

Getting the entries of a ManyToManyField

I'm working with a ManyToManyField and using a ModelMultipleChoice on form, I want to get the entries, but all I get is appname.Extra.none
models.py
class Extra(models.Model):
extra_n = models.CharField(max_length=200)
extra_price = models.IntegerField(default=0)
def __str__(self):
return self.extra_n
class Meal(models.Model):
restaurant = models.ForeignKey(Restaurant, on_delete=models.PROTECT)
category = models.ForeignKey(MealCategory, on_delete=models.PROTECT)
name = models.CharField(max_length=500)
short_description = models.CharField(max_length=500)
image = models.ImageField(upload_to='meal_images/', blank=False)
price = models.IntegerField(default=0)
extras = models.ManyToManyField(Extra, related_name='extras')
def __str__(self):
return self.name
forms.py
class MealForm(forms.ModelForm):
extras = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple(), queryset=Meal.extras)
class Meta:
model = Meal
exclude = ("restaurant",)
views.py
def restaurant_meal(request):
meals = Meal.objects.filter(restaurant = request.user.restaurant).order_by("-id")
return render(request, 'restaurant/meal.html', {"meals": meals})
The output desired is getting the extras added displayed on restaurant_meal view.
you can try change
meals = Meal.objects.filter(restaurant = request.user.restaurant).order_by("-id")
to
meals = Meal.objects.filter(restaurant = request.user.restaurant).prefetch_related('extras').order_by("-id")
and try again.
Doc of this in prefetch_related

Updating fields of model using forms and views on Django 1.7

In models.py my Product model is
class Product(models.Model):
productName = models.CharField(max_length=20, default='1',blank=False,null=False, primary_key = True)
userPhone = models.CharField(max_length=20, default='1')
userid = models.ForeignKey(Account, default='1',null=True)
productDesc = models.TextField(blank=False,null=False, default='1')
productCategory = models.ForeignKey(Category, null=False, default='1')
productPrice = models.DecimalField(default='0',blank=False,null=False, max_digits=6, decimal_places=2)
picture = models.ImageField(upload_to='product_images', blank=True, null=True, default='1')
def __unicode__(self):
return self.productName
The form that I have to add new Products is,
class ProductForm(forms.ModelForm):
productName = forms.CharField(label='Product Name')
productCategory = forms.ModelChoiceField(label='Category', queryset=Category.objects.all())
productDesc = forms.CharField(label='Product Description', widget=forms.Textarea)
productPrice = forms.DecimalField(label='Expected Price')
userPhone = forms.CharField(label='Phone Number')
picture = forms.ImageField(label='Upload Picture')
class Meta:
model = Product
fields = ('productName', 'productCategory', 'productDesc', 'productPrice', 'userPhone', 'picture',)
def clean_productName(self):
productName = self.cleaned_data['productName']
try:
Product.objects.get(productName=productName)
except Product.DoesNotExist:
return productName
raise forms.ValidationError("A product under that name already exits. Rename your product.")
def clean_productCategory(self):
productCategory = self.cleaned_data['productCategory']
def clean_productDesc(self):
productDesc = self.cleaned_data['productDesc']
def clean_productPrice(self):
productPrice = self.cleaned_data['productPrice']
def clean_userPhone(self):
userPhone = self.cleaned_data['userPhone']
def clean_picture(self):
picture = self.cleaned_data['picture']
And to take form input, I have in my views.py file
#login_required(login_url='/accounts/login/')
def newProduct(request):
if(request.method =='POST'):
product_form = ProductForm(request.POST, request.FILES)
if product_form.is_valid():
product = product_form.save(commit=True)
product.save()
else:
print product_form.errors
else:
product_form = ProductForm()
return render(request, 'market/postad.html', {'product_form':product_form} )
I want to update the userid field of Product model to the user_id of the logged in user. How do I go about doing that?
request.user.id
might give me the id of the logged in user. But how do I associate that with the product that is being entered into the database? (I am using MySQL database)
My AUTH_USER_MODEL isn't configured to Account. Is there any way to do it without configuring it?
My Account model is
class Account(models.Model):
user = models.OneToOneField(User)
I imported User from django.contrib.auth.models
In views.py (if your AUTH_USER_MODEL configured to Account)
#login_required(login_url='/accounts/login/', template_name='market/postad.html')
def newProduct(request):
product_form = ProductForm(request.POST or None, request.FILES or None)
if(request.method =='POST'):
if product_form.is_valid():
product = product_form.save(commit=False)
product.userid = Account.objects.get_or_create(user=request.user)
product.save()
else:
print product_form.errors
return render(request, template_name, {'product_form':product_form} )

Categories