I'm having trouble saving a form in a Django app. I want to create an model called 'dataset' from another model called 'image', both of which are mptt models.
models
class Image(MPTTModel):
name = models.CharField(max_length=50, unique=True)
parent = TreeForeignKey('self', null=True, blank=True, related_name='children')
def __unicode__(self):
return self.name
class Dataset(MPTTModel):
name = models.CharField(max_length=50, unique=True)
image = TreeForeignKey(Image, null=True, blank=True, unique=True, related_name='image')
def __unicode__(self):
return self.name
class MPTTMeta:
parent_attr = 'image'
When I try to save a Dataset, I get an integrity error:
IntegrityError at /associate/
column image_id is not unique
Request Method: GET
Request URL: http://127.0.0.1:8000/associate/
Django Version: 1.6.2
Exception Type: IntegrityError
Exception Value:
column image_id is not unique
Exception Location: C:\Python27\lib\site-packages\django\db\backends\sqlite3\base.py in execute, line 450
views.py
def index(request):
images = Image.objects.all()
datasets = []
for i in images:
if i.rank() >= 3:
dataset = Dataset(image=i, name=i.name)
dataset.save()
datasets.append(dataset)
return render(request, 'associate/index.html', {'datasets':datasets})
def learn(request):
if request.method == 'POST':
try:
dataset = request.POST.get('dataset', False)
model = Dataset.objects.get(name=dataset)
if model:
print model.name
else:
print "no model"
except Dataset.DoesNotExist:
return render(request, 'associate/index.html')
else:
return render(request, 'associate/learn.html', {'dataset':model})
You have unique=True in your Dataset model for image field. This means you cannot assign one image to different Dataset instances. But you are doing in it in your index. In your index you trying to create a new dataset for every image every time. But if the Dataset with this image already created - you will get this 'column image_id is not unique' error. Please review your application logic and either remove unique=True or rewrite the behavior.
Related
We are using 'actstream' library and its not updating the actual many2many field id values into history table. Always its updating as an empty list instead of list of ids.
class Parent():
name = models.CharField(max_length=255)
tags = TaggableManager(blank=True)
def __str__(self):
return self.name
class Table1():
name = models.CharField(max_length=255, null=True)
type = models.CharField(max_length=255, null=True)
parent_id = models.ManyToManyField(ParentTable, blank=True, related_name='%(class)s_parent_id')
tags = TaggableManager(blank=True)
def __str__(self):
return self.name
'id' is auto incremented value in Django table. Once we call a save() method, then post_save signal will execute for logging additional information in the actstream table.tags and parent_id is updating as [] instead of user sending values in the actstream_action table.we are using #receiver(post_save) annotation and executing action.send() accordingly
#receiver(post_save)
def capture_models_post_save(sender, instance, created, **kwargs):
userInfo = get_current_user()
action.send(userInfo, verb='created',description='created',action_object=instance, modification=model_to_dict(instance))
I have a model called CarModel and a model called CarModelImage. I want to be able to have images be associated to multiple CarModels. For this I tried using a ManyToManyField.
When I visit the admin page for CarModelImage I get the following error.
ProgrammingError at /admin/cars/carmodelimage/
Exception Value: column cars_carmodelimage.model_id does not exist
Why is it that I can use the many to many in CarModel but not in CarModelImage?
Is there a way I can add id to all my models without having to drop the database?
class CarModel(models.Model):
title = models.CharField(max_length=80)
category = models.ManyToManyField(CarCategory)
...
class Meta:
verbose_name_plural = "Car Models"
def __str__(self):
return self.title
class CarModelImage(models.Model):
timestamp = models.DateTimeField(auto_now_add=True)
image = models.ImageField(upload_to='cars/')
model = models.ManyToManyField(CarModel)
# This is what I had before: model = models.ForeignKey(default=1, on_delete=models.CASCADE, to='cars.CarModel')
def filename(self):
return basename(self.image.name)
class Meta:
verbose_name_plural = "Car Model Images"
ordering = ["timestamp"]
def __str__(self):
return self.filename()
I'm struggling to update records with the writeable nested serializers I've created.
There are many Listing categories for a classifieds app I'm creating that each have a few unique attributes, but they also share many attributes. I have a handful of django models that inherit from a parent Listing model, and one of these models, Battery, contains some nested data. So far I've been able to create Battery records but keep getting AttributeErrors when I try to update them.
I've tried to include only the relevant code. Here are my views:
# views.py
class ListingCreateView(CreateAPIView):
queryset = Listing.objects.all()
def get_serializer_class(self):
category = self.request.data['category']
if category == 1:
return PercussionSerializer
elif category == 6:
return BatterySerializer
return ListingSerializer
class ListingUpdateView(UpdateAPIView):
queryset = Listing.objects.all()
def get_serializer_class(self):
category = self.request.data['category']
if category == 1:
return PercussionSerializer
elif category == 6:
return BatterySerializer
return ListingSerializer
here are my models:
# models.py
## Parent model
class Listing(models.Model):
title = models.CharField(max_length=100)
description = models.TextField(blank=True)
price = models.DecimalField(max_digits=9, decimal_places=2, blank=True, null=True, default=0.00)
## One of the child models
class Battery(Listing):
model_name = models.TextField(blank=True, null=True, default="")
color = models.ForeignKey(Color, on_delete=models.CASCADE, blank=True, null=True)
manufacture_year = models.IntegerField(null=True)
## Model for the nested data in Battery model
class Drum(models.Model):
drum_type = models.CharField(max_length=50, blank=True)
size = models.TextField(blank=True, null=True, default="")
battery = models.ForeignKey(Battery, related_name='drums', on_delete=models.CASCADE, null=True)
and here are my serializers:
# serializers.py
class ListingSerializer(serializers.ModelSerializer):
class Meta:
model = Listing
fields = '__all__'
class DrumSerializer(serializers.ModelSerializer):
class Meta:
model = Drum
fields = ['drum_type', 'size', 'carrier', 'stand', 'cover', 'case', 'sold']
class BatterySerializer(serializers.ModelSerializer):
drums = DrumSerializer(many=True)
class Meta:
model = Battery
fields = ['id', 'title', 'description', 'price', 'model_name', 'color', 'manufacture_year', 'drums']
def create(self, validated_data):
drum_data = validated_data.pop('drums')
battery = Battery.objects.create(**validated_data)
for drum_data in drum_data:
Drum.objects.create(battery=battery, **drum_data)
return battery
def update(self, instance, validated_data):
# Update Listing field values
instance.title = validated_data.get('title', instance.title)
instance.description = validated_data.get('description', instance.description)
instance.price = validated_data.get('price', instance.price)
# Grab the Battery record for this Listing and update its values
instance_battery = Battery.objects.get(pk=instance.pk)
instance_battery.model_name = validated_data.get('model_name', instance_battery.model_name)
instance_battery.color = validated_data.get('color', instance_battery.color)
instance_battery.manufacture_year = validated_data.get('manufacture_year', instance_battery.manufacture_year)
# Check for a list of drums
drum_data = validated_data.pop('drums')
# If it exists
if drum_data:
# Clear the existing drums
instance_battery.drums.clear()
# Create new drums
Drum.objects.bulk_create(
[
Drum(**drum)
for drum in drum_data
],
)
# Save the updated Listing & Battery
instance.save()
instance_battery.save()
# Return the updated Battery
return instance
I feel like I've followed the DRF documentation about writeable nested serializers correctly, but I continue to get this AttributeError when I try to post an update to a Battery record:
AttributeError: Got AttributeError when attempting to get a value for field drums on serializer BatterySerializer.
The serializer field might be named incorrectly and not match any attribute or key on the Listing instance.
Original exception text was: 'Listing' object has no attribute 'drums'.
Judging by the error message I think the Django model inheritance requires a more specific solution that what the DRF documentation provides. Can anybody help me understand how to create the serializers I need to create/update a Battery record that inherits from a Listing model with a nested list of Drum records?
Thanks!
I think the problem appears because the view waits for a Listing instance. I can suggest the following: try to redefine def get_qyeryset(self)
For example:
class ListingUpdateView(UpdateAPIView):
def get_queryset(self):
if self.request.data['category'] == 6:
return Battery.objects.all()
else:
return Listing.objects.all()
def get_serializer_class(self):
category = self.request.data['category']
if category == 1:
return PercussionSerializer
elif category == 6:
return BatterySerializer
return ListingSerializer
Maybe it is not the best way, but it can solve your problem
I am beginner for the Django.
I am trying to make the admin page in which I want to show the columns(user) from the table(BillingProfile) which is the foreign key to the Order Table.
I have created the order model as shown below.
Order Model
class Order(models.Model):
billing_profile = models.ForeignKey(BillingProfile, null=True, blank=True)
order_id = models.CharField(max_length=120, blank=True) # AB31DE3
shipping_address = models.ForeignKey(Address, related_name="shipping_address",null=True, blank=True)
billing_address = models.ForeignKey(Address, related_name="billing_address", null=True, blank=True)
cart = models.ForeignKey(Cart)
def __str__(self):
return self.order_id
The BillingProfile model is as shown below.
BillingProfile Model
class BillingProfile(models.Model):
user = models.OneToOneField(User, null=True, blank=True)
email = models.EmailField()
active = models.BooleanField(default=True)
def __str__(self):
return self.email
And the Code for the Admin Page is as below.
admin.py
class OrderAdmin(admin.ModelAdmin):
list_display = ['__str__', 'billing_profile','get_user']
class Meta:
model = Order
def get_user(self, obj):
return obj.billing_profile.user
admin.site.register(Order,OrderAdmin)
When I am trying to get the user of a specific Billing profile then I am getting the error of 'NoneType' object has no attribute user. this might be due to the fact that few rows of Order table is empty. Can't I show the users of the remaining Rows?
Indeed it is because the profile of the order is none/null, and the admin will show this error. Try:
class OrderAdmin(admin.ModelAdmin):
list_display = ['__str__', 'billing_profile','get_user']
class Meta:
model = Order
def get_user(self, obj):
return obj.billing_profile.user if obj.billing_profile else None
admin.site.register(Order,OrderAdmin)
Adding: obj.billing_profile.user if obj.billing_profile else None, that will only return the user if the obj (order) has a profile.
A simple way is to modify your get_user method:
class OrderAdmin(admin.ModelAdmin):
list_display = ['__str__', 'billing_profile','get_user']
class Meta:
model = Order
def get_user(self, obj):
try:
return obj.billing_profile.user
except AttributeError:
return None
I'm having an issue where I have a non required self many-to-many relationship that when saving a new object to an empty psql db gives me:
Edit: This is when I'm admin saving, there is no view that saves the model.
ValueError: "Video: Teste" needs to have a value for field "from_video" before this many-to-many relationship can be used.
This is my model:
class Video(models.Model):
title = models.CharField(max_length=200, unique=True)
subtitle = models.CharField(max_length=400)
thumbnail = models.ImageField(upload_to='videos/thumbnails')
related_videos = models.ManyToManyField('self', symmetrical=False, blank=True)
This is my save function:
def save(self, *args, **kwargs):
if self.id is None:
# Elasticsearch document creation if word does not exist
video = VideoDocType(title=self.title, subtitle=self.subtitle, thumbnail=str(self.thumbnail))
video.save()
else:
old_value = Video.objects.get(id=self.id)
thumbnail_url = str(self.thumbnail)
video = self._get_video(self)
if video is None:
video = VideoDocType(title=self.title, subtitle=self.subtitle, thumbnail=str(self.thumbnail))
video.save()
else:
if old_value.thumbnail != self.thumbnail:
thumbnail_url = ("videos/thumbnails/" + thumbnail_url)
video.update(title=self.title, subtitle=self.subtitle, thumbnail=str(self.thumbnail))
super(Video, self).save(*args, **kwargs)
My question is, why a non required field gives me the ValueError when there is nothing to be added on the many-to-many field? And how could I fix this?