slugfield does not work the problem is invalid literal for int() with base 10:
I try all English video and some French video
models
from django.utils.text import slugify
class Region(models.Model):
...
slug = models.SlugField(max_length=140, unique=True)
def __str__(self):
return self.name
def _get_unique_slug(self):
slug = slugify(self.name)
unique_slug = slug
num = 1
while Region.objects.filter(slug=unique_slug).exists():
unique_slug = '{}-{}'.format(slug, num)
num += 1
return unique_slug
def save(self, *args, **kwargs):
if not self.slug:
self.slug = self._get_unique_slug()
super().save(*args, **kwargs)
urls
path('<region_slug>', views.detail, name='detail'),
views
def detail(request,region_slug):
region=get_object_or_404(Region ,pk=region_slug)
context = {
.....
'region_slug':region.slug
}
I think your problem is in your view. This line points to the primary key (pk) of your model, but the pk isn't the same as the slug. The pk is referencing the auto-inserted id field.
def detail(request, region_slug):
region = get_object_or_404(Region, pk=region_slug)
You could make the slug field your primary key, but I would suggest rather pointing to the slug field as it stands now.
def detail(request, region_slug):
region = get_object_or_404(Region, slug=region_slug)
Related
I have an application that has a dropdown menu among other things.
The menu is created based on the requirements. I wrote a query that checks the statuses and calculates how many requirements are in a given status. Then he builds a menu out of it. However, I have a problem because sometimes a requisition has been created but no items have been added to it. In that case, my menu shows this as one of the items. This is not what he expects. I would like the query to return and count only those requirements in a given status that have children.
Below I paste the model code and inquiries.
class D_DemandStatus(ModelBaseClass):
status = models.CharField(max_length=20, unique=True)
name = models.CharField(max_length=50)
created_user = models.ForeignKey(User, on_delete=models.PROTECT)
def save(self, *args, **kwargs):
user = get_current_user()
if user and not user.pk:
user = None
if not self.pk:
self.created_user = user
self.modified_by = user
super(D_DemandStatus, self).save(*args, **kwargs)
def __str__(self):
return self.name
class Meta:
verbose_name = 'Demand status'
verbose_name_plural = 'Demands status'
class Demand(models.Model):
name = models.CharField(max_length=500)
status = models.ForeignKey(D_DemandStatus, default=3, on_delete=models.PROTECT, )
insert_user = models.ForeignKey(User, on_delete=models.PROTECT, editable=False)
insert_date = models.DateTimeField(default=datetime.datetime.now, editable=False)
def save(self, *args, **kwargs):
user = get_current_user()
if user and not user.pk:
user = None
if not self.pk:
self.insert_user = user
self.status = D_DemandStatus.objects.get(status='PREPARED')
self.modified_by = user
super(Demand, self).save(*args, **kwargs)
def __str__(self):
return self.name
def submitt(self, *args, **kwargs):
if self.pk :
dict_status = D_DemandStatus.objects.get(status='WAITING')
print(dict_status)
self.demanddetails_set.filter(demand_id = self.pk).update(status=dict_status)
self.status = dict_status
self.save()
def status_actualize(self, *args, **kwargs):
if self.pk :
dict_status = D_DemandStatus.objects.get(status='ORDERED')
items_status = DemandDetails.objects.filter(demand=self.pk).values('status').distinct()
if len(items_status) == 1 and items_status[0]['status'] == dict_status.id :
self.status = D_DemandStatus.objects.get(status='ORDERED')
#elif len(items_status) > 1 :
# self.status = D_DemandStatus.objects.get(status='INPROGRESS')
self.save()
class Meta:
verbose_name = 'Demand'
verbose_name_plural = 'Demands'
class DemandDetails(models.Model):
demand = models.ForeignKey(Demand, on_delete=models.CASCADE, related_name='items')
component = models.ForeignKey(Component, on_delete=models.CASCADE)
order_item = models.ForeignKey(OrderItem, null=True, on_delete=models.PROTECT, editable=False, related_name='demand_details_item')
quantity = models.IntegerField(default=1)
comment = models.CharField(max_length=150, blank=True)
status = models.ForeignKey(D_DemandStatus, default=3, on_delete=models.PROTECT, )
insert_user = models.ForeignKey(User, on_delete=models.PROTECT, editable=False)
insert_date = models.DateTimeField(auto_now_add=True)
def quantityUpdate(self, val):
if self.pk :
self.quantity = val
self.save()
def save(self, *args, **kwargs):
user = get_current_user()
if user and not user.pk:
user = None
if not self.pk:
self.insert_user = user
self.status = D_DemandStatus.objects.get(status='PREPARED')
if not self.pk:
try:
super(DemandDetails, self).save(*args, **kwargs)
except IntegrityError as e:
obj = DemandDetails.objects.get(demand_id=self.demand_id, component_id=self.component_id)
obj.quantity = obj.quantity + 1
obj.save()
else:
super(DemandDetails, self).save(*args, **kwargs)
def __str__(self):
return self.demand.name
class Meta:
verbose_name = 'Demand detail'
verbose_name_plural = 'Demand details'
constraints = [
models.UniqueConstraint(fields=['demand_id', 'component_id'], name='epm - DemandDetail (demand, component)' )
]
The query that works now looks like this:
demand_list = Demand.objects.values('status__name', 'status__id', 'status__status').annotate(count=Count('status__name')).filter(Q(status__status='WAITING') | Q(status__status='PREPARED')).order_by('-status__name')
In this case, however, even if the demand is empty (no items added), it is counted as 1
So I have changed the code a little, but it doesn't work as I would like, because it also counts the individual elements of the demand - which is obvious, because the query returns the subsequent rows that are counted.
demand_list = Demand.objects.values('status__name', 'status__id', 'status__status').annotate(count=Count('status__name'), piece=Count('demanddetails')).filter(Q(piece__gte=1)).filter(Q(status__status='WAITING') | Q(status__status='PREPARED')).order_by('-status__name')
I need to write the query in such a way that I get a list of statuses with numbers of demands only which have derived elements in DemandDetails. If a Demand exists but has no derived elements then it is not taken into account - rather it is counted as 0. This is important because in the extreme case there may be only one Demand which is empty and then I want to have information about it in the menu but with the number 0.
I hope I have managed to write clearly what I chaie.
Please help me to create a suitable query.
Regards
I'm working on my final year project, and I need some help to understand what is actually happening, The problem is that: I hit the Update request through postman which gives the successful message for updating the data. but when I check my Database there is no updated data. I also did the debugging but there was no exception by which I can understand the problem Anyone can please help me?
I'm using
PgAdmin for my database.
Django==4.0.2
djangorestframework==3.13.1
djangorestframework-jwt==1.11.0
djangorestframework-simplejwt==5.0.0
psycopg2==2.9.3**.
My Models:
class Company(Base):
company_name = models.CharField(max_length=255, db_column='Company_Name')
company_email = models.EmailField(unique=True, max_length=255, db_column='company_email')
company_manager_name = models.CharField(max_length=255, db_column='Manager_Name')
company_address = models.CharField(max_length=255, db_column='Company_address')
about_company = models.TextField()
company_website = models.URLField(max_length=200)
is_active = models.BooleanField(default=True, db_column='IsActive', help_text='I will use this for enable/disable '
'a specific record')
class Meta:
db_table: 'Company'
def __str__(self):
return self.company_name
def save(self, *args, **kwargs):
try:
if not self.pk:
self.company_email = self.company_email.replace(" ", "").lower()
super().save()
except Exception:
raise
class Base(models.Model):
"""Following fields are abstract and will be use in All over the project Any time Anywhere"""
create_by = models.BigIntegerField(db_column='CreatedBy', null=True, blank=True, default=0)
create_on = models.DateTimeField(db_column='CreatedOn', auto_now_add=True)
modified_by = models.BigIntegerField(db_column='ModifiedBy', null=True, blank=True, default=0)
modified_on = models.DateTimeField(db_column='ModifiedOn', auto_now=True)
deleted_by = models.BigIntegerField(db_column='DeletedBy', null=True, blank=True, default=0)
deleted_on = models.DateTimeField(db_column='DeletedOn', auto_now=True)
status = models.BigIntegerField(db_column='Status', default=0, help_text='I will use this field for making'
'the status like pending approved and '
'for some other purpose by Default it is '
'Zero which has no meaning', )
class Meta:
abstract: True
serializer.py:
class CompanyUpdateSerializer(serializers.ModelSerializer):
company_name = serializers.CharField(required=True, allow_null=False, allow_blank=False)
company_email = serializers.CharField(required=True, allow_null=False, allow_blank=False)
company_manager_name = serializers.CharField(required=True, allow_null=False, allow_blank=False)
company_address = serializers.CharField(required=True, allow_null=False, allow_blank=False)
about_company = serializers.CharField(required=True, allow_null=False, allow_blank=False)
company_website = serializers.URLField(allow_blank=False, allow_null=False)
class Meta:
model = Company
fields = ['id', 'company_name', 'company_email', 'company_manager_name', 'company_address', 'about_company',
'company_website']
def update(self, instance, validated_data):
try:
instance.company_name = validated_data.get('company_name', instance.company_name)
instance.company_email = validated_data.get('company_email', instance.company_email)
instance.company_manager_name = validated_data.get('company_manager_name', instance.company_manager_name)
instance.company_address = validated_data.get('company_address', instance.company_address)
instance.about_company = validated_data.get('about_company', instance.about_company)
instance.company_website = validated_data.get('company_website', instance.company_website)
instance.save()
return instance
except Exception as e:
raise e
Views.py
def put(self, request, pk=None):
try:
id1 = pk
saved_company = Company.objects.get(pk=id1)
data = request.data
serializer = CompanyUpdateSerializer(instance=saved_company, data=data)
if serializer.is_valid():
serializer.save()
return self.send_response(success=True, code=f'200', status_code=status.HTTP_200_OK,
description='Company is updated')
return self.send_response(code=f'422', status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
description=serializer.errors)
except ObjectDoesNotExist:
return self.send_response(code='422', status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
description="No Company matches the given query.")
except IntegrityError:
return self.send_response(code=f'422', status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
description="Email Already Exist")
except Company.DoesNotExist:
return self.send_response(code=f'422', status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
description="Company Model doesn't exists")
except FieldError:
return self.send_response(code=f'500', description="Cannot resolve keyword given in 'order_by' into field")
except Exception as e:
return self.send_response(code=f'500', description=e)
The problem comes from Company.save() method.
You overrode it as
class Company(Base):
...
def save(self, *args, **kwargs):
try:
if not self.pk:
self.company_email = self.company_email.replace(" ", "").lower()
super().save()
except Exception:
raise
Notice the call of super().save() inside the self.pk is None if statement block.
This will make the actual save method to be called only when the pk is None, meaning that only when a new instance is created, not when an instance is updated.
Moving the super().save() call to be outside the if statement should handle both creating and updating.
class Company(Base):
...
def save(self, *args, **kwargs):
try:
if not self.pk:
self.company_email = self.company_email.replace(" ", "").lower()
super().save(*args, **kwargs)
except Exception:
raise
I am working on a post request in which the user chooses from a list of tags and makes combinations of tags. The combination of tags should then be posted. Nothing should get changed in the Tag table.
These are the models:
models.py
class Tag(models.Model):
name = models.CharField(max_length=256)
language = models.CharField(max_length=256)
objects = models.Manager()
def __str__(self):
"""Return a human readable representation of the model instance."""
return self.name or ''
#property
def tags(self):
tags = self.tagging.values('tag')
return tags.values('tag_id', 'tag__name', 'tag__language')
class Combination(models.Model):
user = models.ForeignKey(CustomUser, on_delete=models.SET_NULL, null=True)
gameround = models.ForeignKey(Gameround, on_delete=models.CASCADE, null=True)
resource = models.ForeignKey(Resource, on_delete=models.CASCADE, null=True)
tag_id = models.ManyToManyField(Tag, null=True)
created = models.DateTimeField(editable=False)
score = models.PositiveIntegerField(default=0)
objects = models.Manager()
def __str__(self):
return str(self.tag_id) or ''
This is the serializer for Combination.
serializers.py
class CombinationSerializer(serializers.ModelSerializer):
tag_id = TagWithIdSerializer(many=True, required=False, write_only=False)
resource_id = serializers.PrimaryKeyRelatedField(queryset=Resource.objects.all(),
required=True,
source='resource',
write_only=False)
gameround_id = serializers.PrimaryKeyRelatedField(queryset=Gameround.objects.all(),
required=False,
source='gameround',
write_only=False)
user_id = serializers.PrimaryKeyRelatedField(queryset=CustomUser.objects.all(),
required=False,
source='user',
write_only=False)
class Meta:
model = Combination
depth = 1
fields = ('id', 'user_id', 'gameround_id', 'resource_id', 'tag_id', 'created', 'score')
def create(self, validated_data):
user = None
request = self.context.get("request")
if request and hasattr(request, "user"):
user = request.user
score = 0
tag_data = validated_data.pop('tag_id', None)
combination = Combination(
user=user,
gameround=validated_data.get("gameround"),
resource=validated_data.get("resource"),
created=datetime.now(),
score=score
)
combination.save()
for tag_object in tag_data[0]:
combination.tag_id.add(tag_object)
return combination
def to_representation(self, instance):
rep = super().to_representation(instance)
rep['tag_id'] = TagWithIdSerializer(instance.tag_id.all(), many=True).data
return rep
I have tried posting the following JSON object to the database:
{
"gameround_id": 2015685170,
"resource_id": 327888,
"tag_id": [{"id": 2014077506, "name": "corwn","language": "en"}]
}
I am getting a ValueError: Field 'id' expected a number but got 'name'.
How can I fix this issue?
you need to provide tag id for each tag not all tag data,
Try like this
{
"gameround_id": 2015685170,
"resource_id": 327888,
"tag_id": [2014077506,2014077507]
}
Im using django for a web app and i am creating REST API views. Is there a way i can access two tables in one view? If not, how can can i retrieve a non-foreign key column from a related record. The below code is retrieving a vase record based on a URL parameter. I want to access the artistName which is stored in artist table (a one-to-many with Vase table), not artist_id which is stored in Vase
class FilterVases(generics.ListAPIView):
serializer_class = VaseSerializer
def get_queryset(self):
queryset = Vase.objects.all()
artist_id = self.request.query_params.get('artist_id')
if artist_id is not None:
queryset = queryset.filter(artist_id=artist_id)
vaseID = self.request.query_params.get('vaseID')
if vaseID is not None:
queryset = queryset.filter(vaseID=vaseID)
return queryset
edited to add
This is models for Artist and Vase:
class Artist(models.Model) :
artistID = models.CharField(max_length=10)
artistName = models.CharField(max_length=100)
class Vase(models.Model):
vaseID = models.CharField(max_length=10)
vaseRef = models.CharField(max_length=255,blank=True,null=True)
inscription = models.CharField(max_length=255,blank=True,null=True)
fabric = models.CharField(max_length=100, blank=True,null=True)
subject = models.CharField(max_length=255,blank=True,null=True)
technique = models.CharField(max_length=100,blank=True,null=True)
height = models.FloatField(max_length=100,blank=True,null=True)
diameter = models.FloatField(max_length=100,blank=True,null=True)
shape = models.ForeignKey(Shape, on_delete=models.CASCADE)
artist = models.ForeignKey(Artist, on_delete=models.CASCADE)
provenance = models.ForeignKey(Provenance, on_delete=models.CASCADE)
collection = models.ForeignKey(Collection, on_delete=models.CASCADE)
In the Vase model add this:
def artist_name(self):
return self.artist.artistName
Hence, it will look like:
class Vase(models.Model):
vaseID = models.CharField(max_length=10)
vaseRef = models.CharField(max_length=255,blank=True,null=True)
inscription = models.CharField(max_length=255,blank=True,null=True)
fabric = models.CharField(max_length=100, blank=True,null=True)
subject = models.CharField(max_length=255,blank=True,null=True)
technique = models.CharField(max_length=100,blank=True,null=True)
height = models.FloatField(max_length=100,blank=True,null=True)
diameter = models.FloatField(max_length=100,blank=True,null=True)
shape = models.ForeignKey(Shape, on_delete=models.CASCADE)
artist = models.ForeignKey(Artist, on_delete=models.CASCADE)
provenance = models.ForeignKey(Provenance, on_delete=models.CASCADE)
collection = models.ForeignKey(Collection, on_delete=models.CASCADE)
def artist_name(self):
return self.artist.artistName
In the VaseSerializer add the 'artist_name' to the fields Meta.
If you want to add this custom fields to all Vase Model fields, refer to this topic Django Rest framework, how to include '__all__' fields and a related field in ModelSerializer ?
class VaseSerializer(serializers.ModelSerializer):
class Meta:
model = models.Vase
fields = '__all__'
extra_fields = ['artist_name']
def get_field_names(self, declared_fields, info):
expanded_fields = super(VaseSerializer, self).get_field_names(
declared_fields, info)
if getattr(self.Meta, 'extra_fields', None):
return expanded_fields + self.Meta.extra_fields
else:
return expanded_fields
Below should your view:
class FilterVases(generics.ListAPIView):
serializer_class = VaseSerializer
def get_queryset(self):
queryset = Vase.objects.all()
query_artist = self.request.query_params.get('artist_name')
if query_artist is not None:
try:
artist = Artist.objects.get(artistName=query_artist)
queryset = queryset.filter(artist=artist)
except:
pass
vaseID = self.request.query_params.get('vaseID')
if vaseID is not None:
queryset = queryset.filter(vaseID=vaseID)
return queryset
i have this on my model
class Social(db.Model):
__tablename__ = 'social_auth_usersocialauth'
id = db.Column('id',db.Integer, primary_key=True)
provider = db.Column('provider',db.String(32))
extra_data = db.Column('extra_data',db.String())
uid = db.Column('uid',db.String(255))
def __init__(self,id, provider, extra_data, uid):
self.id = id
self.provider = provider
self.extra_data = extra_data
self.uid = uid
def __repr__(self):
return self.uid
and when i call it to my view, i just get the uid, yes i know because in my model i just returned it's uid, the question is, how can i return all of it's table's columns ?
like id, provider, also extra_data column,,,
Thank you.
The simpler way is to comment your repr function and return the Social object and use it's attributes by calling
social = Social.query.first() # example
id = social.id
providor = object.providor
...
But if you really want to do it this way you can return all attributes in repr by:
def __repr__(self):
return self.id, self.providor, self.extra_data, self.uid
and changing this in you views to this and get all values by::
id, providor, extra_data, uid = Social.query.first() # example