Set primary key in Django - django

The title is not entirely accurate, but I do not know how to explain, so I took a screenshot of where my problem is, and I will try to explain what I am trying to achieve.
I have a vehicle model, and when I create a new vehicle object, the name of vehicles just says Vehicle object (1) How can I change my model, or serializer (or something else) so that will show some unique value of the object.
Here is my model:
class Vehicle(models.Model):
make = models.CharField(max_length=100, blank=True)
model = models.CharField(max_length=300, blank=True)
license_plate = models.CharField(max_length=7, blank=True)
vehicle_type = models.CharField(max_length=20, blank=True)
seats = models.IntegerField(default=4,
validators=[
MaxValueValidator(70),
MinValueValidator(4)],
)
year = models.IntegerField(_('year'), default=datetime.today().year - 10, validators=[
MinValueValidator(1975), max_value_current_year])
inspected = models.BooleanField(default=True)
# fuel_type
# fuel_price
created_at = models.DateTimeField(auto_now_add=True)

You can implement a __str__ method that returns a string, for example:
class Vehicle(models.Model):
# …
def __str__(self):
return f'{self.make} ({self.year})'
You can thus return any string, and that will be presented by default in the Django admin and the drop downs.

Related

how to filter data in different models in django?

my models
class Player(TimeStampedModel):
name = models.CharField(max_length=200)
email = models.CharField(max_length=200)
email_verified = models.BooleanField(default=False, blank=True)
phone = models.CharField(max_length=200)
phone_verified = models.BooleanField(default=False, blank=True)
company_id = models.ImageField(upload_to=get_file_path_id_card, null=True,
max_length=255)
company_id_verified = models.BooleanField(default=False, blank=True)
team = models.ForeignKey(Team, related_name='player', on_delete=models.DO_NOTHING)
def __str__(self):
return self.name
this is my model , how to filter data in multiple model?
You can use a Queryset to filter by modal object's field.
You can use this to also filter relationships on models.
In your example, you can do a filter of all the Player entries that have a Character that have Weapon with strength > 10
Player.objects.filter(character__weapon__strength__gt=10)
You can also separate them out into 3 variables for readability purposes.
player_q = Player.objects.filter(character__isnull=False)
ch_q = player_q.filter(weapon__isnull=False)
wpn_dmg = ch_q.filter(strength__gt=10)
Please note that filters are lazy and thus don't return actual model instances untill they're evaluated. I think in this case gt returns an instance.
This documentation goes over all the fieldset lookups you can do with QuerySet object methods filter(), get(), and exclude()

How to copy a object data to another object in Django?

I am trying to create an E-Commerce Website and I am at the Final Step i.e. Placing the Order. So, I am trying to add all the Cart Items into my Shipment model. But I am getting this error.
'QuerySet' object has no attribute 'product'
Here are my models
class Product(models.Model):
productId = models.AutoField(primary_key=True)
productName = models.CharField(max_length=200)
productDescription = models.CharField(max_length=500)
productRealPrice = models.IntegerField()
productDiscountedPrice = models.IntegerField()
productImage = models.ImageField()
productInformation = RichTextField()
productTotalQty = models.IntegerField()
alias = models.CharField(max_length=200)
url = models.CharField(max_length=200, blank=True, null=True)
class Customer(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
name = models.CharField(max_length=100, null=True, blank=True)
email = models.EmailField(max_length=100)
profileImage = models.ImageField(blank=True, null=True, default='profile.png')
phoneNumber = models.CharField(max_length=10, blank=True, null=True)
address = models.CharField(max_length=500, blank=True, null=True)
class Order(models.Model):
customer = models.ForeignKey(Customer, on_delete=models.SET_NULL, blank=True, null=True)
dateOrdered = models.DateTimeField(auto_now_add=True)
orderCompleted = models.BooleanField(default=False)
transactionId = models.AutoField(primary_key=True)
class Cart(models.Model):
product = models.ForeignKey(Product, on_delete=models.SET_NULL, blank=True, null=True)
order = models.ForeignKey(Order, on_delete=models.SET_NULL, blank=True, null=True)
quantity = models.IntegerField(default=0, blank=True, null=True)
dateAdded = models.DateTimeField(auto_now_add=True)
class Shipment(models.Model):
customer = models.ForeignKey(Customer, on_delete=models.SET_NULL, blank=True, null=True)
orderId = models.CharField(max_length=100)
products = models.ManyToManyField(Product)
orderDate = models.CharField(max_length=100)
address = models.CharField(max_length=200)
phoneNumber = models.CharField(max_length=13)
I just removed additional functions i.e. __str__ and others.
Here is the views.py
def orderSuccessful(request):
number = Customer.objects.filter(user=request.user).values('phoneNumber')
fullAddress = Customer.objects.filter(user=request.user).values('address')
timeIn = time.time() * 1000 # convert current time in milliSecond
if request.method == 'POST':
order = Shipment.objects.create(customer=request.user.customer, orderId=timeIn,
orderDate=datetime.datetime.now(), address=fullAddress,
phoneNumber=number)
user = Customer.objects.get(user=request.user)
preOrder = Order.objects.filter(customer=user)
orders = Order.objects.get(customer=request.user.customer, orderCompleted=False)
items = orders.cart_set.all() # Here is all the items of cart
for product in items:
product = Product.objects.filter(productId=items.product.productId) # error is on this line
order.products.add(product)
Cart.objects.filter(order=preOrder).delete()
preOrder.delete()
order.save()
else:
return HttpResponse("Problem in Placing the Order")
context = {
'shipment': Shipment.objects.get(customer=request.user.customer)
}
return render(request, "Amazon/order_success.html", context)
How to resolve this error and all the cart items to field products in Shipment model?
Your model is not really consistent at all. Your Cart object is an m:n (or m2m - ManyToMany) relationship between Product and Order. Usually, you would have a 1:n between Cart and Product (a cart contains one or more products). One Cart might be one Order (unless you would allow more than one carts per order). And a shipment is usually a 1:1 for an order. I do not see any of this relationships in your model.
Draw your model down and illustrate the relations between them first - asking yourself, if it should be a 1:1, 1:n or m:n? The latter can be realized with a "through" model which is necessary if you need attributes like quantities.
In this excample, we have one or more customers placing an order filling a cart with several products in different quantities. The order will also need a shipment fee.
By the way: bear in mind that "filter()" returns a list. If you are filtering on user, which is a one to one to a unique User instance, you would better use "get()" as it returns a single instance.
Putting in into a try - except or using get_object_or_404() makes it more stable.
product = Product.objects.filter(productId=items.product.productId)
should be something like:
product = product.product
not to say, it becomes obsolete.
It looks like you make a cart for a product by multiple instances of Cart, the problem is you try to access the wrong variable, also you don't need to filter again when you already have the instance, make the following changes:
carts = orders.cart_set.all() # Renamed items to carts for clarity
for cart in carts:
product = cart.product
order.products.add(product) # The name order is very misleading makes one think it is an instance of Order, actually it is an instance of Shipment
As mentioned above in my comment your variable names are somewhat misleading, please give names that make sense to any variable.

Django, detect if object.filter returns 0 objects

I got such table structure
class Item(models.Model):
id = models.AutoField(primary_key=True)
class Car(models.Model):
vin_number = models.CharField(max_length=250, null=True, blank=True)
item = models.OneToOneField(Item, on_delete=models.CASCADE)
name = models.CharField(max_length=1000, null=True)
year = models.IntegerField(null=True)
class Yacht(models.Model):
name = models.CharField(max_length=1000, default='')
boat_type = models.CharField(max_length=1000, default='', null=True)
item = models.OneToOneField(Item, on_delete=models.CASCADE)
description = models.TextField(default='')
year = models.IntegerField(null=False, default=0)
So, both Car and Yacht has relation with Item table
If I have only item id in request, what is the right way to write such query
data = request.POST
item = Car.objects.filter(item_id=data['item_id']).first()
if not item:
item = Yacht.objects.filter(item_id=data['item_id']).first()
Is there any way not to use if/else statement?
You don't need to look into the Car and Yacht model. Directly use the Item model's OneToOne relationship
item = Item.objects.filter(id = data['id']).first
This item has a specific id that relates to one of the other model. You can access them using
if item.car:
car = item.car
else:
yacht = item.yacht
But I guess you also need to add {{ related_name='tags', related_query_name='tag' }} to your OneToOne field for both car and yacht.
I would recommend that you check this out https://kite.com/python/docs/django.db.models.ForeignKey.
For more detail go to https://docs.djangoproject.com/en/3.0/topics/db/examples/one_to_one/
You need to use exists().
Car.objects.filter(item_id=data['item_id']).exists()
Yacht.objects.filter(item_id=data['item_id']).exists()
It returns you True or False.
Links to official docs.

Django : pre selection or tags. model relations

Django Version is 2.1.7
Hello, i have a OneToMany Relation and i ask my self if there is a possibility to make some kind of pre-selection (Tags or so?) for my Farmers?
Because not every Farmer has or wants Chickens or he is specialist in Cows only.
Means, right now, whenever i want to assign an individual Animal to a Farmer, i see all Farmers displayed in my Django Admin. With a growing Number of Farmers it gets confusing. So i thought to insert some Kind of Model Field in my Farmers Model... like chickens = true or not true and cows = true or not true or to introduce a new model for every species.
My Goal is, to assign a set of species to a every farmer. So that the Next time i want to add a chicken django shows only Farmers that will work with Chickens on their Farmland, it makes no sense to Display all Farmers, when some Farmers know that they handel only a specific set of species.
As a Newbie i would guess i have to make some new models for every Species with a ManyToMany Relation? So Farmers >< Species X, Y, Z < Indiviual Anmial.
Thanks
class Farmers(models.Model):
name = models.CharField(max_length=100)
farm_img = models.ImageField(upload_to='farm/', max_length=255, null=True, blank=True)
slug_farm = models.SlugField(blank=True)
<...>
class Chickens(models.Model):
farmer = models.ForeignKey(Farmers, on_delete=models.CASCADE, null=True)
chickenname = models.CharField(max_length=100)
<...>
class Cows(models.Model):
farmer = models.ForeignKey(Farmers, on_delete=models.CASCADE, null=True)
cowname = models.CharField(max_length=100)
<...>
class Rabbits(models.Model):
farmer = models.ForeignKey(Farmers, on_delete=models.CASCADE, null=True)
cowname = models.CharField(max_length=100)
<...>
If we are using postgres as DB then arrayFieldlink
can be a good option for doing this job.
from django.contrib.postgres.fields import ArrayField
class Farmers(models.Model):
.... necessary fields
SAMPLE_CHOICES = (
('CHICKEN', 'CHICKEN'),
('COW, 'COW'),
('No Species', 'No Species')
.....
)
choices = ArrayField(
models.CharField(choices=SAMPLE_CHOICES, max_length=10, blank=True, default='No Species'),
)
Now whenever we need to filter on Farmer model based on choices we can do this like following
Farmer.objects.filter(choices__contains=['cow'])
Update
As you are using django-mysql database, following thing by django-mysql link here we can have field feature like ListField link and can easily achieve this.
class ChickenFarmers(models.Model):
name = models.CharField(max_length=100)
farm_img = models.ImageField(upload_to='farm/', max_length=255, null=True, blank=True)
slug_farm = models.SlugField(blank=True)
class CowFarmers(models.Model):
name = models.CharField(max_length=100)
farm_img = models.ImageField(upload_to='farm/', max_length=255, null=True, blank=True)
slug_farm = models.SlugField(blank=True)
class RabbitsFarmers(models.Model):
name = models.CharField(max_length=100)
farm_img = models.ImageField(upload_to='farm/', max_length=255, null=True, blank=True)
slug_farm = models.SlugField(blank=True)
class Chickens(models.Model):
farmer = models.ForeignKey(ChickenFarmers, on_delete=models.CASCADE, null=True)
chickenname = models.CharField(max_length=100)
class Cows(models.Model):
farmer = models.ForeignKey(CowFarmers, on_delete=models.CASCADE, null=True)
cowname = models.CharField(max_length=100)
class Rabbits(models.Model):
farmer = models.ForeignKey(RabbitsFarmers, on_delete=models.CASCADE, null=True)
cowname = models.CharField(max_length=100)
'''
I think at this point this will give you best relief
'''

Django instance - Combine two attribute values in model

Can someone tell me how to combine two or more attribute values of in another field by using instance?
Models.py:
fn_id = models.ForeignKey(FilemNumber, null=True, blank=True)
ln_id = models.ForeignKey(LineNumber, null=True, blank=True)
pn_id = models.ForeignKey(PhotoNumber, null=True, blank=True)
title = models.CharField(max_length=255,blank=True, null=True)
I want to combine fn_id, ln_id and pn_id and save the combination of the three values into field title.
You can do this:
from django import models
class BaseModel(models.Model):
fn_id = models.ForeignKey(FilemNumber, null=True, blank=True)
ln_id = models.ForeignKey(LineNumber, null=True, blank=True)
pn_id = models.ForeignKey(PhotoNumber, null=True, blank=True)
class YourModel(models.Model):
common = models.OneToOneField(BaseModel)
# I suppose that you want to get title, so let define title method
# if obj is an instance of YourModel, you can access title like this:
# obj.title
#property
def title(self):
return '{}{}{}{}'.format(self.id, self.common.fn_id,
self.common.ln_id, self.common.pn_id)
Lets read this article: https://docs.djangoproject.com/en/1.8/ref/models/fields/#onetoonefield