ValueError badly formed hexadecimal UUID string django ListView - python

Assume all imports done.
I have a model like this:
class Package(models.Model):
uuid = models.UUIDField(default=uuid.uuid4, editable=False)
name = models.CharField(max_length=400)
Then I want to use generic ListView like so:
class PackageList(ListView):
model = Package
template_name = 'package/list.html'
All with url like so:
url(r'^package/list/$', views.PackageList.as_view(), name='package_list'),
When I visit the localhost:8000, I get
ValueError at /package/list/
badly formed hexadecimal UUID string
However, a DetailView generic view loads the detail based on the uuid successfully, without any issues.
The error comes up only when using the ListView.
What am I doing wrong?

Figured.
The url sequence was the culprit. Having sequence this way fixed it:
url(r'^travel/add/$', views.TravelAdd.as_view(), name='travel_add'),
url(r'^travel/list/$', views.TravelList.as_view(), name='travel_list'),
url(r'^travel/(?P<uuid>[\w-]+)/$', views.TravelDetail.as_view(), name='travel_detail'),
Previously, it was this:
url(r'^travel/add/$', views.TravelAdd.as_view(), name='travel_add'),
url(r'^travel/(?P<uuid>[\w-]+)/$', views.TravelDetail.as_view(), name='travel_detail'),
url(r'^travel/list/$', views.TravelList.as_view(), name='travel_list'),

Related

How can I make a field in Django models that concatenates a specific string to each record's id?

I have made a field facility_id in Django models that should concatenate a specific string "ACCTS-" on the left with each record's id on the right,
My model class is below:
class Facility(models.Model):
...
id = models.BigAutoField(primary_key=True)
facility_id = models.CharField(max_length=50, default=print(f'{"ACCTS-"}{id}'), editable=False)
...
I want to the facility_id field to be storing special and readable human friendly facility_id's of the form: ACCTS-1, ACCTS-2, ACCTS-3, ... corresponding to each individual id.
The migrations didn't throw any errors, however When I try to create the records for this table in the Django Admin, am getting an IntegrityError of:
IntegrityError at /admin/ACCTS_CLYCAS/facility/add/
NOT NULL constraint failed: ACCTS_CLYCAS_facility.facility_id
How do I fix this problem, or what could be the easiest way to implement my problem.
The migrations didn't throw any errors, however When I try to create the records for this table in the Django Admin
That makes sense, since you have set the default=None. Indeed, print(…) returns None and only prints the value to the standard output channel (stdout). It will thus not prepend the value of the id with ACCTS.
If the facility_ids are all just the id prefixed with ACCTS-, you can work with a #property instead:
class Facility(models.Model):
id = models.BigAutoField(primary_key=True)
#property
def facility_id(self):
return f'ACCTS-{self.id}'
You can also try using a post save signal.
Add blank = True to facility_id and then use a post save signal to update the value of facility_id.
You can watch this tutorial on how to use Django Signals

Django 3 models.Q - app_lable gets displayed inside html

since I upgraded to Django 3.x I have a strage behaviour.
Imaging the following field at your models.py
content_type = models.ForeignKey(ContentType, limit_choices_to=filter_choice, on_delete=models.CASCADE, null=True, blank=True)
which refers to:
filter_choice = models.Q(app_label='App', model='model_x') | models.Q(app_label='App', model='model_y')
If I now display the content_type field on my html templates it look like this: "App| Model Y" which looks quite stupid, same goes for Django admin. Is this a Bug? I'm asking because on Django 2.2.7 (Latest version of 2.x) I dont had this behaviour and only model_x and model_y have been displayed as expected.
Would be awesome if only model_x and model_y getting displayd without there app lables. Is there any solution for this, maybe a new option that comes with django 3.x?
Thanks in advance :)
If I now display the content_type field on my html templates it look like this: "App| Model Y" which looks quite stupid.
This is how the __str__ of a ContentType is implemented. Indeed, if we take a look at the source code [GitHub], we see:
class ContentType(models.Model):
# …
def __str__(self):
return self.app_labeled_name
# …
#property
def app_labeled_name(self):
model = self.model_class()
if not model:
return self.model
return '%s | %s' % (model._meta.app_label, model._meta.verbose_name)
If you want to render the model name however, you can for example use:
{{ object.content_type.model_class._meta.verbose_name }}
It makes sense to include the app label, since the same model name can be used in different apps, hence it is possible that your project has two Model Ys, in two different apps.
Furthermore it is not very common to render a ContentType in the template. Normally this is part of the technical details of your project, that you likely do not want to expose. If you need to show the type of the object in a GenericForeignKey, you can simply follow the GenericForeignKey, and render the ._meta.verbose_name of that object.

Django model serialization problem with default fields

Inside of my app model, I use IntegerRangeField fields:
from django.db import models
from django.contrib.postgres.fields import IntegerRangeField
from django.contrib.postgres.validators import RangeMinValueValidator, RangeMaxValueValidator
from psycopg2.extras import NumericRange
class MyModel(models.Model):
...
field = IntegerRangeField(default=NumericRange(400, 600), validators=[
RangeMinValueValidator(1),
RangeMaxValueValidator(1000)
])
...
The "default" attributes are used in the admin panel UI only, and are not needed anywhere else.
If I add them after migration, they work smoothly. However, if I add them before I run makemigrations, I get this message:
ValueError: Cannot serialize: NumericRange(400, 600, '[)') There are
some values Django cannot serialize into migration files.
I don't even want the default values to be saved to my PostgreSQL database, I just want to not have to remove and bring them back every time I run makemigrations.
Any ideas?
(Didn't work: a custom object with "lower" and "higher" attributes, a single integer, a string, a tuple)
Python: 3.6.6, Django: 2.1.2, PostgreSQL: 11.0
Try to move default value calculation into separate function:
def get_default_range():
return NumericRange(400, 600)
class MyModel(models.Model):
field = IntegerRangeField(default=get_default_range, validators=[
RangeMinValueValidator(1),
RangeMaxValueValidator(1000)
])
In this case migration was successfully generated:
operations = [
migrations.AddField(
model_name='comment',
name='field',
field=django.contrib.postgres.fields.ranges.IntegerRangeField(
default=play.models.get_default_range,
validators=[django.contrib.postgres.validators.RangeMinValueValidator(1),
django.contrib.postgres.validators.RangeMaxValueValidator(1000)]),
),
]
I was able to solve this problem using the string representation of the range:
IntegerRangeField(default='[400, 600]')
django==3.0.5
psycopg2==2.8.5
EDIT I should point out that the original question was 2 years old, but at least in django 3.1, their is a serializer that you must register separately.
You need to register the serializer that is provided by django.
from psycopg2.extras import NumericRange
from django.contrib.postgres.serializers import RangeSerializer
from django.db.migrations.writer import MigrationWriter
MigrationWriter.register_serializer(NumericRange, RangeSerializer)
This piece was not in the documentation, but then you can add your defaults as you'd expect:
class AgeDivision(models.Model):
name = models.CharField(max_length=50, unique=True)
age_range = fields.IntegerRangeField(
unique=True, blank=True, default=NumericRange(None, None))
as for where to put this, it just needs to go along side any module that is only loaded once. The documentation didn't specify where to put custom serializers (as least that I could find), but I'd say put them in the migrations/__init__.py file for any app that requires the serializer. here's the documentation on migration serialization: https://docs.djangoproject.com/en/3.1/topics/migrations/#custom-serializers

An efficient way to save parsed XML content to Django Model

This is my first question so I will do my best to conform to the question guidelines. I'm also learning how to code so please ELI5.
I'm working on a django project that parses XML to django models. Specifically Podcast XMLs.
I currently have this code in my model:
from django.db import models
import feedparser
class Channel(models.Model):
channel_title = models.CharField(max_length=100)
def __str__(self):
return self.channel_title
class Item(models.Model):
channel = models.ForeignKey(Channel, on_delete=models.CASCADE)
item_title = models.CharField(max_length=100)
def __str__(self):
return self.item_title
radiolab = feedparser.parse('radiolab.xml')
if Channel.objects.filter(channel_title = 'Radiolab').exists():
pass
else:
channel_title= radiolab.feed.title
a = Channel.objects.create(channel_title=channel_title)
a.save()
for episode in radiolab.entries:
item_title = episode.title
channel_title = Channel.objects.get(channel_title="Radiolab")
b = Item.objects.create(channel=channel_title, item_title=item_title)
b.save()
radiolab.xml is a feed I've saved locally from Radiolab Podcast Feed.
Because this code is run whenever I python manage.py runserver, the parsed xml content is sent to my database just like I want to but this happens every time I runserver, meaning duplicate records.
I'd love some help in finding a way to make this happen just once and also a DRY mechanism for adding different feeds so they're parsed and saved to database preferably with the feed url submitted via forms.
If you don't want it run every time, don't put it in models.py. The only thing that belongs there are the model definitions themselves.
Stuff that happens in response to a user action on the site goes in a view. Or, if you want this to be done from the admin site, it should go in the admin.py file.

Returning extended fields in JSON

I have two tabels(Ingredient_Step and Ingredient) in on relation as you can see below:
Models.Py
class Ingredient_Step(models.Model):
ingredient = models.ForeignKey(Ingredient)
Step = models.ForeignKey(Step)
def __unicode__(self):
return u'{}'.format(self.Step)
class Ingredient(models.Model):
IngredientName = models.CharField(max_length=200,unique=True)
Picture = models.ImageField(upload_to='Ingredient')
def __unicode__(self):
return u'{}'.format(self.IngredientName)
In a function, i need serialize a JSON object from a query that returns from "Ingredient_step", but I need send the field "IngredientName", who comes from "Ingredient" table.
I try using "ingredient__IngredientName" but it fails.
Views.Py:
def IngredientByStep(request):
if request.is_ajax() and request.GET and 'id_Step' in request.GET:
if request.GET["id_Step"] != '':
IngStp = Ingredient_Step.objects.filter(Step =request.GET["id_Step"])
return JSONResponse(serializers.serialize('json', IngStp, fields=('pk','ingredient__IngredientName')))
How i can call extends field from a relation?
Thanks
This "feature" of Django (and many ORM's like SQLAlchemy) are called Lazy Loading, meaning data is only loaded from related models if you specifically ask for them. In this case, build your IngStp as a list of results, and make sure to access the property for each result before serializing.
Here's an example of how to do that: Django: Include related models in JSON string?

Categories