Cannot assign "<QuerySet [<Contact: zak>]>": "Booking.contact" must be a "Contact" instance - django

I have an issue, I created a form where users can make a reservation (in detail view) of a unique product. So one user can have multiples booking. The form used contain email and username. This form is in my detail.html with include variable.
{% include 'store/list.html' with list_title=name %}
So, When I run my server, go to the reservation page, put an username, email and submit, I have an error instead to redirect to an another page.
models.py:
from django.db import models
class Contact(models.Model):
email = models.EmailField(max_length=100)
name = models.CharField(max_length=200)
def __str__(self):
return self.name
class Marque(models.Model):
name = models.CharField(max_length=200, unique=True)
def __str__(self):
return self.name
class Model(models.Model): #Plusieurs models pour une marque
reference = models.IntegerField(null=True)
created_at = models.DateTimeField(auto_now_add=True)
available = models.BooleanField(default=True)
name = models.CharField(max_length=200)
picture = models.URLField()
marque = models.ForeignKey(Marque, on_delete=models.CASCADE)
def __str__(self):
return self.name
class Booking(models.Model): #plusieurs réservation pour un contact
created_at = models.DateTimeField(auto_now_add=True)
contacted = models.BooleanField(default=False)
marque = models.OneToOneField(Marque, on_delete=models.CASCADE)
model = models.OneToOneField(Model, on_delete=models.CASCADE)
contact = models.ForeignKey(Contact, on_delete=models.CASCADE)
def __str__(self):
return self.contact.name
views.py:
...
def detail(request, model_id):
model = get_object_or_404(Model, pk=model_id)
#marques = [marque.name for marque in model.marque.all()]
#marques_name = " ".join(marques)
if request.method == 'POST':
email = request.POST.get('email')
name = request.POST.get('name')
contact = Contact.objects.filter(email=email)
if not contact.exists():
#If a contact is not registered, create a new one
contact = Contact.objects.create(
email = email,
name = name
)
#If no album matches the id, it means the form must have been tweaked
#So returning a 404 is the best solution
model = get_object_or_404(Model, pk=model_id)
booking = Booking.objects.create(
contact = contact,
model = model
)
#Make sure no one can book the model again
model.available = False
model.save()
context = {
'model_name': model.name
}
return render(request, 'store/merci.html', context)
message = "Le model est {}. Conçu par la marque {}".format(model.name, model.marque)
context = {
"model_name" : model.name,
"model_marque" : model.marque,
"model_id": model.id,
"thumbnail" : model.picture
}
return render(request, 'store/detail.html', context)
search_form.html inside of detail.html:
<div class="container">
<div class="col-lg-12 detail-separator">
<form class="col-md-6 col-md-offset-3 text-center" action="{% url 'store:search' %}" method="get" accept-charset="utf-8">
<div class="form-group">
<label for="searchForm">Chercher un Model</label>
<input id="searchForm" class="form-control" name="query">
</div>
<span class="help-block" id="helpBlock">Trouvez le model de voiture de vos rêves !</span>
</form>
</div>
</div>

You contact query returns a queryset:
contact = Contact.objects.filter(email=email)
You then try to use contact as if it were a single Contact object:
booking = Booking.objects.create(
contact = contact,
model = model
)
This is why Django complains that it got a Queryset instead of a Contact.
You need to select one Contact even if the Queryset only contains one single object. E.g.
contacts = Contact.objects.filter(email=email)
if contacts.exists():
contact = contacts[0]
else:
#If a contact is not registered, create a new one
contact = Contact.objects.create(
email = email,
name = name
)
Or, preferably:
try:
contact = Contact.objects.get(email=email)
except DoesNotExist:
contact = Contact.objects.create(
email = email,
name = name
)

Related

How to fix add to cart functionality in django?

I'm building an ecommerce platform and I want to create the add to cart functionality in the website. But for some reason the Product Id is showing null.
Here's the codes:
models.py
class Products(models.Model):
user = models.ForeignKey(User, on_delete = models.CASCADE)
title = models.CharField(max_length = 255)
product_category = models.CharField(choices = CATEGORY_CHOICES, max_length = 100)
description = models.TextField()
price = models.FloatField(max_length= 5)
class Cart(models.Model):
user = models.ForeignKey(User, on_delete = models.CASCADE)
products = models.ForeignKey(Products, on_delete = models.CASCADE)
views.py
def add_cart(request):
product_id = Products.id
new_product = Cart.objects.get_or_create(id=product_id, user=request.user)
return redirect('/')
templates
<div class="product-wrapper">
<h1 style="font-size:24px">{{product.title}}</h1>
<div class="product-price">
<p style="text-decoration-line:line-through;">$ {{product.price}}</p>
<a href="{% url 'add-product' product.product_id %}">Add to cart<a>
</div>
When I try to click this link it gives me this error: Field 'id' expected a number but got <django.db.models.query_utils.DeferredAttribute object at 0x000002468A4F8550>.
Any suggestion will be really helpful. Thank you
Finally, I've fixed this.
view.py
def add_to_cart(request, slug):
products = Products.objects.get(slug=slug)
ncart = Cart.objects.create(user=request.user, products=products)
ncart.save()
return redirect('/')
template
<div class="product-wrapper">
<h1 style="font-size:24px">{{product.title}}</h1>
<div class="product-price">
<p style="text-decoration-line:line-through;">$ {{product.price}}</p>
<a href="{% url 'add-to-cart' product.slug %}">Add to cart<a>
</div>
urls.py
path('cart/add/<slug:slug>', views.add_to_cart, name = 'add-to-cart')
Considering you've got Products instance already, in that case
Query directly like:
new_product = Cart.objects.get_or_create(products=Products)
If you want to query from the product_id, do it like that:
product_id = Products.pk
new_product = Cart.objects.get_or_create(products_id=product_id)
In addition:
request.user contains a dictionary, you can't pass it directly to query. And the user field has name buyer, so change that query like that:
product_id = Products.pk
new_product = Cart.objects.get_or_create(products=Products, buyer_id=request.user['pk'])

How can I get the ids of a queryset from a model and store them into a different model using a form?

I have a model called 'Competicion', with some objects and another model called 'Participante'. This second model has two fields: a foreignkey with the user and another foreingkey to 'Competicion'.
In the view, I've made queryset from 'Competicion' and with a for loop in the template I've given each object the button of the form.
With storing the user of the current session I have no problem but I want the form to know which object of the queryset it is to grab its id. #I have no problem with choices I just don't include them to save space
Models.py
class Competicion(models.Model):
ciudad = models.CharField(max_length=50, null=True, choices=Ciudades_a_elegir, default="Ninguna")
nombre = models.CharField(max_length=20, null=True, choices=Competiciones_a_elegir, default="Ninguna")
titulo = models.CharField(max_length=40, null=True)
fecha = models.DateField(null=True)
participantes = models.IntegerField(null=True)
flyer = models.ImageField(null=True, upload_to='imagenes', default='Ninguna')
def __str__(self):
return self.nombre + " " + self.titulo
class Participante(models.Model):
competicion = models.ForeignKey(Competicion, on_delete=models.CASCADE, null=True, blank=True)
participantes = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
def __str__(self):
return self.competicion.nombre + " " + self.competicion.titulo
forms.py
class ParticipanteForm(ModelForm):
class Meta:
model = Participante
exclude = ['competicion', 'participantes']
views.py
def competiciones(request):
qs = Competicion.objects.all()
form = ParticipanteForm(request.POST or None)
if form.is_valid():
nombres = form.save()
nombres.competicion = ???#Help me
nombres.participantes = request.user
nombres.save()
return redirect('home')
context = {
'object_list':qs,
'form':form,
}
return render(request, "competiciones.html", context)
template
{% for i in object_list %}
<ul>
<li>{{i.nombre}}</li>
<li>{{i.ciudad}}</li>
<li>{{i.titulo}}</li>
<li>{{i.fecha}}</li>
<li>{{i.participantes}}</li>
{% if i.flyer %}
<img src="{{i.flyer.url}}" width="100px" >
{% endif %}
<li><form action="" method="POST">
{% csrf_token %}
<p> {{ form.competicion}} </p>
<p>{{form.participantes}}</p>
<input type="submit" name="Inscribirse" value="Inscribirse">
</form> </li>
</ul>
{% endfor %}
This is only like 1 course. In number one there is the different fields of the Competicion Model. And number two is the button of the form to the Participante Model, which fields are hidden and take the id of the course and the user. So I have a lot of these both courses displayed in the web. The function of the Particpante Model is to store the people who register in the course and the course itself.
def competiciones(request):
qs = Competicion.objects.all()
form = ParticipanteForm(request.POST or None)
if form.is_valid():
data = form.save()
data.participantes_id = request.user
for i in qs:
data.competicion_id = i.id
data.save()
return redirect('home')

Rendering a custom tag with a foreign key into templates issues

Hi this is the model I am working with
from django.db import models
from users.models import CustomUser
class Project(models.Model):
id = models.AutoField(primary_key=True)
user = models.ForeignKey(CustomUser, on_delete=models.PROTECT, editable=False)
name = models.CharField(max_length=20, editable=False)
total = models.DecimalField(max_digits=6, decimal_places=2, editable=False)
created = models.DateTimeField(auto_now_add=True, editable=False, null=False, blank=False)
def __str__(self):
return self.name
The class is populated by an HTML form using this view:
def homepage(request):
if request.method == "POST":
project = Project()
name = request.POST.get('name')
total = request.POST.get('total')
created = datetime.datetime.now()
user = request.user
project.user = user
project.name = name
project.total = total
project.created = created
project.save()
#return HttpResponse(reverse("homepage.views.homepage"))
return render(request, 'homepage.html')
else:
return render(request, 'homepage.html')
and so I have added a custom tag into my app which is a function
#register.filter
def monthlyTotal(user):
this_month = now().month
return Project.objects.filter(
created__month=this_month,
user=user
).aggregate(
sum_total=Sum('total')
)['sum_total']
I call the tag like this in template
<p>Total monthly sales = {{ user.username|monthlyTotal }}</p>
however I get an error saying Field ID expected a number but got 'grandmaster' which is the name of my test user who has multiple Project objects.. if I switch to user.id I get no error but it displays None which makes sense because when I look at my project section in admin the field user is populated by the username not the id so there would be no project where user=id
You need to use the user, not the username, so:
<p>Total monthly sales = {{ user|monthlyTotal }}</p>

I can't add foreignkey values

I need to add data to the database For that, I'm trying some code. But I can't add foreignkey values. The code throws exceptions. Here are my views.py, models.py code and exceptions.
first try:
views.py
def notification(request):
user = request.user
if request.method == 'POST':
property_id = request.POST['property_id']
owner = request.POST['owner_id']
property_object = Property.objects.get(id=property_id)
owner_object = Property.objects.get(owner=owner)
notification = user, "have intrested in your property"
property_object.notify.add(user)
notifications = Notifications.objects.create(notification=notification, owner=owner_object
,property=property_object)
notifications.save()
it throws exception
ValueError: Field 'id' expected a number but got 'hafis'.
second try
views.py
def notification(request):
user = request.user
if request.method == 'POST':
property_id = request.POST['property_id']
owner = request.POST['owner_id']
property_object = Property.objects.get(id=property_id)
notification = user, "have intrested in your property"
property_object.notify.add(user)
notifications = Notifications.objects.create(notification=notification, owner=owner,
property=property_id)
notifications.save()
it throws exception
ValueError: Cannot assign "'hafis'": "Notifications.owner" must be a "User" instance.
models.py
class Property(models.Model):
owner = models.ForeignKey(User, null=True, blank=True, on_delete=models.CASCADE)
headline = models.CharField(max_length=255)
city = models.CharField(max_length=100)
location = models.CharField(max_length=100)
facilites = models.TextField()
rent = models.CharField(max_length=200)
images = models.FileField(upload_to='media/uploads',null=True)
email = models.EmailField()
mobile = models.IntegerField(null=True)
date = models.DateTimeField(auto_now_add=True)
notify = models.ManyToManyField(User, default=None, blank=True, related_name='Liked')
def __str__(self):
return self.headline
class Notifications(models.Model):
owner = models.ForeignKey(User, null=True, blank=True,on_delete=models.CASCADE)
property = models.ForeignKey(Property, null=True, blank=True,on_delete=models.CASCADE)
notification = models.TextField()
date = models.DateTimeField(auto_now_add=True)
def __str_(self):
return self.notification
HTML code
{% if accomodations %}
{% for accomodation in accomodations %}
<form action="{% url 'notification' %}" method="post">
{% csrf_token %}
<input type="hidden" name="owner_id" value="{{ accomodation.owner }}">
<button id="request-btn" name="property_id" value="{{ accomodation.id }}" class="btn btn-primary">Contact info:</button>
</form>
You need to pass the users instance. You can get user by this line of code
owner = User.objects.all().get(username=owner)
Note:
Every user should have differnt usernames
ValueError: Cannot assign "'hafis'": "Notifications.owner" must be a "User" instance. you're just passing in the ID but it requires it to be a User object.
def notification(request):
user = request.user
if request.method == 'POST':
property_id = request.POST['property_id']
owner = User.objects.get(id=request.POST['owner_id'])
property_object = Property.objects.get(id=property_id)
notification = user, "have intrested in your property"
property_object.notify.add(user)
notifications = Notifications.objects.create(notification=notification, owner=owner,
property=property_id)
notifications.save()

Problem in displaying objects from ForeignKey in Django

I am having two models Patient and Ipd, Patient can have multiple Ipd. I am trying to get Patient Info in IpdForm but don't know where I am getting wrong
I have already tried "qs = Ipd.objects.get(patient__id=patient_id)" , "qs = Ipd.objects.filter(patient__id=patient_id)" but nothing worked
models.py :
class Patient(models.Model):
name = models.CharField(max_length=200);
phone = models.CharField(max_length=20);
address = models.TextField();
Patient_id = models.AutoField(primary_key=True);
Gender= models.CharField(choices=GENDER, max_length=10)
consultant = models.CharField(choices=CONSULTANT, max_length=20)
def __str__(self):
return self.name
class Ipd(models.Model):
reason_admission = models.CharField(max_length=200, blank=False)
presenting_complaints = models.CharField(max_length=200,)
ipd_id = models.AutoField(primary_key=True)
rooms = models.ForeignKey(Rooms,on_delete=models.CASCADE, blank=False)
date_of_admission = models.DateField(("Date"),
default=datetime.date.today)
patient = models.ForeignKey(Patient, on_delete=models.CASCADE, blank=False, default = "")
def __str__(self):
return self.patient.name
forms.py :
class PatientForm(forms.ModelForm):
class Meta:
model = Patient
fields = ['name','phone','address','Patient_id','consultant','Gender']
class IpdForm(ModelForm):
class Meta:
model = Ipd
fields = ['patient', 'reason_admission', 'presenting_complaints',
'rooms', 'date_of_admission']
views.py:
#login_required
def ipd (request,patient_id):
formtwo = IpdForm()
qs = Ipd.objects.filter(patient__Patient_id=patient_id)
if request.method=="POST":
formtwo = IpdForm(request.POST)
if formtwo.is_valid() :
instance = formtwo.save(commit=False)
instance.save
else:
return HttpResponse(formtwo.errors)
else:
formtwo = IpdForm()
return render(request, 'newipd.html', {'a':qs,'form2':formtwo})
urls.py :
url(r'^order/ipd/(?P<patient_id>\d+)/$', my_order.ipd, name='ipd'),
html :
<div class="card-panel">
<span class="blue-text text-darken-2">Name : {{ab.name}}</span> <br>
<span class="blue-text text-darken-2">Phone : {{ a.phone }}</span><br>
<span class="blue-text text-darken-2">Address : {{ a.address }}</span><br>
<span class="blue-text text-darken-2">Gender : {{ a.Gender }}</span><br>
</div>
You can simply access your Patient model by using
Ipd.objects.filter(patient_id=patient_id)
Note the single underscore at the first patient_id.
You only use double underscores while accessing a related model, but in this case you have a foreign key directly in your Ipd model.
Edit
I just saw, that you created your own Patient_Id field.
I would suggest to recreate your Patient model without the field Patient_id.
Django will create an ID field itself.
If you really want to keep your own field, than the correct access to it would be:
Ipd.objects.filter(patient_patient_id=patient_id)
But I would not recommend that.
There are a lot more flaws in your code, like keeping all fields lowercase in a model, etc.
Please try to refer to the Django docs and maybe Python docs.
Keeping you code clear would simplify a lot of things.