Models:
class Item(models.Model):
name = [...] # unique
quantity = [..integer_field..]
class Sales(models.Model):
sold_to = [...]
sold_item = foreign key to Item
sold_quantity = [..integer field..]
I want to make sure that if the selected Item has the quantity of 5, and you pass 6 or more to the sold_quantity, throw a validation error saying "You have only X in stock and wanted to sell Y".
I tried to override the save method, but however I try to do so, it changes nothing. When I try to access self.sold_item, it returns the name of the selected item.
When I try to do item.objects.get(name=self.sold_item), whatever I do it returns just the name of the item and I can't access other fields (known as Quantity).
Conc:
Item.objects.get(name=self.sold_item) returns the name of the item.
using the same but Filter instead of Get returns a queryset, which contains <Item: the items name> and I can't access other fields of it.
Per a comment on the question, this is the answer
have you tried this self.sold_item.quantity ? you can just check if self.sold_item.quantity < self.sold_quantity: raise ....
Related
I have a model than has a lot of models.BooleanField declarations.
class a_lot_of_booleans(model.Models):
old_or_new = models.BooleanField(default=False,verbose_name="is it an old or a new item")
product_for_teens = models.BooleanField(default=False,verbose_name="is this product for teens")
in_original_package = models.BooleanField(default=False,verbose_name="is this product in original package?")
Which then is used in some other classes like:
class product_for_sale(a_lot_of_booleans):
U_Id = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
product_name=models.CharField(max_length=50)
class product_for_buying(a_lot_of_booleans):
U_Id = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
product_name=models.CharField(max_length=50)
The class a_lot_of_booleans might change over time. Some booleans might get added some might get removed. What I need is to display a list of several entries, of the verbose_name, of only the true fields on one of the classes that inherit the a_lot_of_booleans class and the value of product_name, belonging to specific user.
What I"m trying in the views.py is the following:
def view_rfps(request):
list=product_for_sale.objects.all().filter(U_Id=request.user)
for item in list:
values=item._meta.fields
for value in values:
res=item.objects.filter(**{value:'True'}) ##<< lines that fail
print(res)
the above code fails on res=item.objects.filter(**{value:'True'}) on "Manager isn't accessible via search_for_constructor_rfp instances"
The idea later to pass on the res variable to view, however I cannot pass this point.
I have several items in list and for every list several boolean fields, that I"m not sure what they names gonna be in a future, so I cannot just use product_for_sale. in template later.
Any suggestion how to display the verbose name of unknown boolean field name ?
edit
Found a way:
def view_rfps(request):
list=product_for_sale.objects.all().filter(U_Id=request.user)
for item in list:
values=item._meta.fields
for value in values:
temp=getattr(item,value.name)
if temp:
print(value.verbose_name)
But if someone knows more efficient way, I"d love to hear
This is what worked for me:
def view_rfps(request):
list=product_for_sale.objects.all().filter(U_Id=request.user)
for item in list:
values=item._meta.fields
for value in values:
temp=getattr(item,value.name)
if temp:
print(value.verbose_name)
So I have models like so:
class Leaderboard(models.Model):
pass
class Column(models.Model):
leaderboard = models.ForeignKey(Leaderboard, related_name="columns", on_delete=models.CASCADE)
related_columns = models.ManyToManyField(self)
index = models.PositiveIntegerField()
And serializers like so:
class ColumnSerializer(ModelSerializer):
related_columns = serializers.PrimaryKeyRelatedField(queryset=Column.objects.all(), many=True)
class Meta:
model = Column
fields = ('leaderboard', 'related_columns', 'index',)
class LeaderboardSerializer(ModelSerializer):
children = ColumnSerializer(many=True)
class Meta:
model = Leaderboard
fields = ('columns',)
So what I'd like to do is verify that any columns added to related_columns for ColumnSerializer already belong to its Leaderboard parent. I have tried many times to access the Leaderboard or a Leaderboard ID (like by manually specifying id in fields) during creation of the ColumnSerializer to verify, but LeaderboardSerializer` is not initialized before Column so I cannot verify the details.
Basically, I want to modify queryset=Column.objects.all() to be queryset=self.instance.leaderboard.columns.all()
However I don't have access to Leaderboard inside Column. For example, if I access self.parent.instance/initial inside ColumnSerializer it is None until inside Leaderboard.validate_columns(). One thing I've thought of is to just do the validation on the Leaderboard side, but I still think it should be "doable" to do this validation inside Column in case I ever want to edit those directly, without first going through a Leaderboard...
Here is how I solved this problem:
def validate_columns(self, columns):
if not columns:
raise serializers.ValidationError("Leaderboards require at least 1 column")
# Make sure all column indexes are unique
indexes = [column['index'] for column in columns]
if len(set(indexes)) != len(columns):
raise serializers.ValidationError("Columns must have unique indexes!")
# Make sure all column keys are unique
keys = [column["key"] for column in columns]
if len(set(keys)) != len(columns):
raise serializers.ValidationError("Columns must have unique keys!")
# Validate that column.computation_indexes points to valid columns
for column in columns:
if 'computation_indexes' in column and column['computation_indexes']:
for index in column['computation_indexes'].split(","):
try:
if int(index) not in indexes:
raise serializers.ValidationError(f"Column index {index} does not exist in available indexes {indexes}")
except ValueError:
raise serializers.ValidationError(f"Bad value for index, should be an integer but received: {index}.")
return columns
I make sure that the columns are unique (both in their keys and indexes) and that the columns they are referencing exist as well.
Here i want to do is that ,i want to list all the person who didn't blocked me.Here in the table Blocked there is two columns name
who and whose . In whose column i store the id of the person whom i blocked and in the who column i store my id. Now i want to do that, when the blocked person click on
view-person button in my web page he cannot see profile of the person one who blocked him.
when i did this query blocked_list = Blocked.objects.filter(whose = user_id). Now i got the list of the persons who blocked me. Now i want to exclude all this person from this query total_profiles = persons.objects.all().exclude(blocked_list). How can i do this.
models.py
class persons(models.Model):
full_name = models.CharField(max_length=200)
class blocked(models.Model):
who = models.ForeignKey(persons)
whose = models.IntegerField(null=True)
views.py
def blocked(request):
blocked_list = Blocked.objects.filter(whose = user_id)
total_profiles = persons.objects.all().exclude(blocked_list)
return render_to_response('profiles/view_all.html', {'total_profiles':total_profiles,'}, context_instance=RequestContext(request),)
please correct the question if it is not correct.
You can try this:
total_profiles = persons.objects.all().exclude(id__in = blocked_list.values_list('id', flat=True))
It's untested, but adapted from this answer.
Some notes:
if persons has the default manager, you can omit all().
whose does not have an index, so it will become slow when your dataset gets big. You can use a ForeignKey field instead of an IntegerField
the common convention is to capitalize class names and to write model names in singular i.e. Person instead of persons
I am reading Excel using xlrd. One of the columns has the Bank name, which is linked to vehicle model via Foreign Key. When xlrd finishes reading a row, it should save that record to vehicle table. However getting the actual pk value and error that Vehicles.bank must a Banks instance.
After checking dozens of questions related to this issue, I found this one the most similar one, but still I am not getting the expected result.
The relevant Vehicle model section is as follows:
class Vehicles(models.Model):
stock = models.CharField(max_length=10, blank=False, db_index=True)
vin = models.CharField(max_length=17, blank=False, db_index=True)
sold = models.DateField(blank=True, null=True, db_index=True)
origin = models.CharField(max_length=10, blank=False, db_index=True)
bank = models.ForeignKey('banks.Banks', db_column='bank', null=True)
I am using python 2.7, django 1.5.4 and Postgresql 9.2.5. Dbshell utility does show that banks table has a Foreign contraint referring to vehicles table, via banks(id).
Since I am not using a form for this particular part, I think it does not matter whether I use a ModelForm or not.
Current scenario: Excel file has FBANK as the cell value. There is an existing record in banks table that contains FBANK in its name column, id=2. The python line is:
def bank(value):
return Banks.objects.get(name=value).id
With the above line, error is:
Cannot assign "2": "Vehicles.bank" must be a "Banks" instance.
If I remove the ".id" at the end, error is then:
Banks matching query does not exist.
Appreciate your help.
Ricardo
When saving Vehicle you need to pass Banks instance with corresponding bank name. See example, I suppose that you have all data in corresponding cells from 0 to 4, replace with your own cells numbers:
def get_bank_instance(bank_name):
try:
bank = Banks.objects.get(name=bank_name)
except Banks.DoesNotExist:
return None
return bank
# reading excel file here, we have list of cells in a row
for cell in cells:
bank = get_bank_instance(cell[4])
if bank:
# get other cells values to be saved in Vehicles
stock, vin, sold, origin = cell[0], cell[1], cell[2], cell[3]
Vehicles.create(bank=bank, stock=stock, vin=vin, sold=sold, origin=origin)
You also can create save instance of Vehicles passing bank id directly:
b_id = Banks.objects.get(name=bank_name).id
Vehicles.create(bank_id=b_id, stock=stock, vin=vin, sold=sold, origin=origin)
Update:
create() is a built-in model method to create and save into database model instance. If you are asking about "Add a classmethod on the model class" in Django docs, this is not the case, because you are just using built-in method for the model. For some cases you can use custom method for creating new models, but I would do so if I had to pass a lot of default attributes for the new instance.
Also, it's possible to create and save new model instance by using save():
bank_instance = Banks.objects.get(name=bank_name)
vehicle = Vehicles()
vehicle.bank = bank_instance
vehicle.stock = stock
vehicle.vin = vin
vehicle.sold = sold
vehicle.origin = origin
# without save() data will not be saved to db!
vehicle.save()
It's quite long and you always need to remember to call .save(), so it's a good idea to use .create()
You should be returning a Banks instance when you want to assign it to a Vehicle model instance; so you should not have the .id part at the end of the return value for your bank() method.
Secondly, if it says that it isn't finding the Banks instance, then you should check the value of your value parameter to see what it is and try to manually do a Banks.objects.get from your database. If it can't be found then there is probably another reason for this other than using the Django ORM incorrectly.
When you are assigning instances to other instances in Django, for example setting the Bank for a Vehicle it must be an instance of the model and not the id or pk value of model; this is stated in the other StackOverflow question that you reference in your question.
I have this view, right:
def thisviewright(request,pk):
theadd = adds.objects.filter(id=pk)
theaddlist = adds.objects.filter(category=add.category)
return render_to_response..
And i'm trying to get the category so i display all other adds that have the same category.
As i'm not passing the category from a URL, i have to get it from the add, who's ID i am passing.
But i'm getting an error:
Queryset has no attribute Category
The model is as follows:
class adds(models.Model):
title = models.CharField(max_length=255)
category = models.ForeignKey('categories')
...
class categories(models.Model):
title = models.CharField(max_length=255)
So long question short, how do i get the related adds from the same category by using the category from the object i'm passing?
In the first line of the view, you're returning a queryset, not an object. While this queryset will contain only one objec, others constructed using a filter will have multiple members.
To return an object as opposed to a queryset with that line, use either of the following lines:
theadd = adds.objects.get(id=pk)
theadd = adds.objects.filter(id=pk)[0]
You should only ever use the first on unique indexed properties (i.e. id), as it will fail with an error if there is more than one object that matches the criterion.