I have a Cruise offer class related to a model called SpecialInterest. I now realize that I have the same exact thing going on in my LandOffer model (elsewhere). So I want to get rid of the cruise.SpecialInterest and replace it with the land.SpecialInterest.
This is my error:
Error: One or more models did not validate:
cruise.cruiseoffer: 'special_interest' has an m2m relation with model land.models.SpecialInterest, which has either not been installed or is abstract.
I dropped the CruiseOffer table, but when I syncdb I fail.
Help?
class CruiseOffer(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=300) # Field name made lowercase.
name_enca = models.CharField(max_length=300, blank=True) # Field name made lowercase.
name_frca = models.CharField(max_length=300, blank=True) # Field name made lowercase.
supplier = models.ForeignKey('CruiseSupplier')
#special_interest = models.ManyToManyField('SpecialInterest')
special_interest = models.ManyToManyField('land.models.SpecialInterest')
def __unicode__(self):
return "%6d %s" % (self.id, self.name,)
Right syntax is:
from land.models import SpecialInterest
...
class Crui...
...
special_interest = models.ManyToManyField(SpecialInterest)
Related
I have a model for applications, which among many attributes have a category. This category is in fact a key to another model that has the category ID, its name, and so on.
class Application(models.Model):
title = models.CharField(max_length=50)
vendor = models.CharField(max_length=50, default="Unknown", null=False)
.
.
.
category = models.ForeignKey('ApplicationCategory', related_name='applications', null=False, default=1, on_delete=models.SET_DEFAULT)
class ApplicationCategory(models.Model):
name = models.CharField(max_length=20, null=False)
description = models.CharField(max_length=200, null=False)
Then, on the Django REST serializers side I have the serializer for the applications:
class SoftwareSerializer(serializers.ModelSerializer):
category = serializers.PrimaryKeyRelatedField(queryset=ApplicationCategory.objects.all())
class Meta:
model = Application
fields = ['id', 'title', ... 'category']
Which is generating the expected API view, with a dropdown for the categories, but showing them as the ApplicationCategory objects and not giving me their name.
API showing Category dropdown with objects instead of names
Is there a way to access attributes of those objects to show the name in the dropdown, for usability sake?
I have also tried creating a CategorySerializer object (class CategorySerializer(serializers.ModelSerializer)) and then using it as category = CategorySerializer(many=False) but instead of dropdowns, I get open text fields for the attributes of the category.
Am I trying to do something that is not expected to work?
try to define the desired text in str method for your ApplicationCategory class:
class ApplicationCategory(models.Model):
name = models.CharField(max_length=20, null=False)
description = models.CharField(max_length=200, null=False)
#example
def __str__(self):
return '%s: %s' % (self.name , self.description)
i encountered the following problem when i try to migrate list of models one of which contains a ManyToMany field.
class Item(models.Model):
File "C:\Users\helin\Downloads\Django\E-commerce\Farmers\Farmersapp\models.py", line 60, in Item
sluger = farmer.First_Name
AttributeError: 'ManyToManyField' object has no attribute 'First_Name'
Below are the models i created.any help is appreciated.Thank you
class Farmer(models.Model):
id = models.AutoField(default=1,primary_key=True)
First_Name = models.CharField(max_length=15)
Last_Name = models.CharField(max_length=15)
def __str__(self):
return self.First_Name+" "+self.Last_Name
def get_farmer(self):
return self.farmer.First_Name+" " +self.farmer.Last_Name
class Item(models.Model):
id = models.AutoField(default=1,primary_key=True)
category = models.CharField(choices=CATEGORY_CHOICES, max_length=6)
price = models.FloatField()
description = models.TextField(blank=True)
image = models.ImageField()
farmer = models.ManyToManyField(Farmer, through='ItemAmount',related_name='item')
sluger = farmer.First_Name
slug = models.SlugField(default=sluger)
def __str__(self):
return self.category
class ItemAmount(models.Model):
farmer = models.ForeignKey(Farmer, on_delete=models.CASCADE)
item = models.ForeignKey(Item, on_delete=models.CASCADE)
quantity = models.IntegerField(default=1)
First, would suggest to take a look at Python style guide, like lowercase attribute names, etc.
Django auto-creates id primary-key field on every model, unless other field is set as primary-key. So, this part can be safely avoided.
get_farmer method - how is it different from str? Also, these are model instance methods ((self)), so there is no self.farmer field on Farmer object - this will fail.
class Farmer(models.Model):
# id AutoFied is created by default by django, so no need to specify
# id = models.AutoField(default=1,primary_key=True)
first_name = models.CharField(max_length=15)
last_name = models.CharField(max_length=15)
def __str__(self):
return self.first_name + " " + self.last_name
farmer = models.ManyToManyField() - as it is ManyToMany, this means many farmers, so it is better to name field farmers, also same applies to reverse relation - Farmer might have multiple items - related_name=items.
sluger - is it a field? Also, it might have many farmers, so which one to pick?
slug - referencing self fields in default is not good idea, better set default in forms.
You can make slug CharField and set its value in save() method for example.
class Item(models.Model):
# id AutoFied is created by default by django, so no need to specify
# id = models.AutoField(default=1,primary_key=True)
category = models.CharField(choices=CATEGORY_CHOICES, max_length=6)
price = models.FloatField()
description = models.TextField(blank=True)
image = models.ImageField()
farmers = models.ManyToManyField(
Farmer,
through='ItemAmount',related_name='items'
)
slug = models.SlugField()
def __str__(self):
return self.category
You can start with minimum working models and add new fields / methods one by one - it would be easier to debug and you will have base working app.
I have the following models in Django:
class campaign(models.Model):
start_date = models.DateField('Start Date')
end_date = models.DateField('End Date')
description = models.CharField(max_length=500)
name = models.CharField(max_length=200)
active_start_time = models.TimeField()
active_end_time = models.TimeField()
last_updated = models.DateTimeField('Date updated',auto_now=True)
active = models.BooleanField(default=True)
client_id = models.ForeignKey('client',on_delete=models.PROTECT)
def __unicode__(self):
return u'%d | %s | %s' % (self.id,self.name, self.description)
class campaign_product(models.Model):
product_id = models.ForeignKey('product',on_delete=models.PROTECT)
last_updated = models.DateTimeField('Date updated',auto_now=True)
campaign_id = models.ForeignKey('campaign',on_delete=models.PROTECT)
class product(models.Model):
name = models.CharField(max_length=200)
description = models.CharField(max_length=500)
sku = models.CharField(max_length=200,blank=True,null=True)
retail_price = models.DecimalField(decimal_places=2,max_digits=11)
discount_price = ((1,'Yes'),(0,'No'))
discounted_price = models.DecimalField(decimal_places=2,max_digits=11,blank=True,null=True)
category_id = models.ForeignKey('category',on_delete=models.PROTECT)
last_updated = models.DateTimeField('Date updated',auto_now=True)
active = models.BooleanField(default=True)
def __unicode__(self):
return u'%d | %s' % (self.id, self.name)
I also have the following serializer:
class campaignProductSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = campaign_product
fields = ('product_id', 'campaign_id')
And the following view set behavior in the urls.py file:
class campaignProductViewSet(viewsets.ModelViewSet):
queryset = campaign_product.objects.filter(campaign_id__start_date__lte=datetime.now(),campaign_id__end_date__gte=datetime.now(),campaign_id__active__exact=True)
serializer_class = campaignProductSerializer
My problem is I need to include the name field from the products model in my query results when for instance a request is made on http://127.0.0.1:8000/campaign_product/1/. Currenly this request returns only the product_id and the campaign_id. I tried making the serializer as follows:
class campaignProductSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = campaign_product
fields = ('product_id', 'campaign_id', 'product.name')
But then the service returns the following error:
Field name `product.name` is not valid for model `campaign_product`.
I event tried using product__name with and without quotes. Without quotes it tells me that there is no such variable, and with quotes it gives the is not valid for model error similar to the above. Heeelp! Getting this extra field is proving to be a pain :-(
What you want will need to look something more like this:
class campaignProductSerializer(serializers.HyperlinkedModelSerializer):
product_name = serializers.CharField(source='product_id.name')
class Meta:
model = campaign_product
fields = ('product_id', 'campaign_id', 'product_name')
P.S. As an unrelated side note, it is generally a convention in Python code to name classes with CamelCase, such as Campaign, CampaignProduct, Product, and CampaignProductSerializer.
Edit: P.P.S. Originally, I had put written the product_name field with source='product.name'. This was actually due to me looking at the code too quickly and making assumptions based on Django conventions. Typically, with a Django ForeignKey, you would name the ForeignKey field after the model you are linking to, rather than explicitly naming it with _id. For example, the CampaignProduct model would typically be written with product = ForeignKey(...) and campaign = ForeignKey(...). In the background, Django will actually use product_id and campaign_id as the database field names. You also have access to those names on your model instances. But the product and campaign variables on your model instances actually return the objects which you are referring to. Hopefully that all makes sense.
I have ManyToMany field in model and i want to query it from another model which has _set field by default:
class Airport(models.Model):
name = models.CharField(max_length=1024, blank=True, null=True)
def __unicode__(self):
return unicode(self.name)
class Agent(models.Model):
name = models.CharField(max_length=1024, blank=True, null=True)
airports = models.ManyToManyField(Airport)
def __unicode__(self):
return unicode(self.name)
So query like:
a=Agents.objects.filter(airports_name_contains='asd')
works fine. But:
b=Airport.objects.filter(agent_set__name__contains='agent_')
gives
Cannot resolve keyword 'agent_set_name' into field
I want to query exactly Airport model. Any suggestions?
oops, my bad. I found solution. Django representaion of manytomany field shows "agent_set" in the lookup, but the field itself is "agent":
agents=Airport.objects.filter(agent_name_contains='agent_')
Here is my code:
models.py
class TblUser(models.Model):
uid = models.IntegerField(primary_key=True, db_column='ID') # Field name made lowercase.
username = models.CharField(max_length=3072, db_column='UserName', blank=True) # Field name made lowercase.
password = models.CharField(max_length=3072, db_column='PassWord', blank=True) # Field name made lowercase.
datesstart = models.DateTimeField(null=True, db_column='datesStart', blank=True) # Field name made lowercase.
datesend = models.DateTimeField(null=True, db_column='datesEnd', blank=True) # Field name made lowercase.
num = models.IntegerField(null=True, db_column='Num', blank=True) # Field name made lowercase.
power = models.IntegerField(null=True, db_column='Power', blank=True) # Field name made lowercase.
email = models.CharField(max_length=12288, blank=True)
class Meta:
db_table = u'tbl_user'
def __unicode__(self):
return '%d--%s--%d'%(self.uid,self.username,self.power)
views.py
from app.models import TblUser
def appendUser(self,name,pwd):
#I add a new user,and the primary_key:uid is autoincrement in datebase
user = TblUser.objects.create(username=name,password=pwd)
print user.uid#None
When I call the appendUser(),it will insert a new record into datebase, and the user(TblUser's instance) only have two valid fields(username,password), the other is empty.
How can I get the user.uid because I want handle other things by using it?
You should use an AutoField not an IntegerField for the pk: https://docs.djangoproject.com/en/1.4/ref/models/fields/#autofield
You might want to read this post, different approach using ModelForm:
Get Primary Key after Saving a ModelForm in Django