im using django 2.1.8 and mongodb
model.py
class Article(models.Model):
title = models.CharField("title", default="", max_length=20)
text = models.CharField("comment", default="", max_length=120)
the one object i have
[
{
"id": 1,
"title": "test",
"comment": "there is a
linebreak"
}
]
views.py
a = Article.objects.filter(text__icontains="\r\n").all()
b = Article.objects.filter(text__icontains="there").all()
It finds a but not b.
As long as icontains includes the "\r\n" i can find all things normal. But a user wont search for "\r\n linebreak". how does it work without "\r\n"?
Related
So I have a blog type of website where I'm trying to use the API to get a list of articles filtered by their topic. Here is the relevant portion of my ArticleDetailPage() class with the API field:
class ArticleDetailPage(Page):
"""Article detail page."""
...
topic = models.ForeignKey('articles.ArticleTopic', null=True, blank=True, on_delete=models.SET_NULL)
...
api_fields = [
...
APIField('topic', serializer=serializers.StringRelatedField(many=False)),
...
]
And here's my ArticleTopic() class:
#register_snippet
class ArticleTopic(models.Model):
"""
Article topics that resides in Snippets.
"""
name = models.CharField(max_length=100)
slug = AutoSlugField(
populate_from='name',
editable=True,
max_length=100,
verbose_name='slug',
allow_unicode=True,
help_text='A slug to identify articles by this topic.'
)
panels = [
FieldPanel('name'),
FieldPanel('slug')
]
class Meta:
verbose_name = 'Article Topic'
verbose_name_plural = 'Article Topics'
ordering = ['name'] # Alphabetial ordering
def __str__(self):
return self.name
So far so good, when I take a look at the API list of posts, instead of showing the topic attribute as its ID and other data, it's represented as its string representation (i.e. a topic like space or comets). However, when I try to filter the API by appending:
&topic=space
to the HTML, I get an error saying:
Field 'id' expected a number but got 'space'.
Instead of using the StringRelatedField(many=False) serializer, I switched to
APIField('topic', serializer=serializers.PrimaryKeyRelatedField(many=False, read_only=True))
So each topic is represented only as its ID and when I perform the same filtering above but using the ID instead of the string name, it works!
Ideally, I'd want to just filter using the string name instead of the ID for other purposes in my project. Anyone have any experience on this or would like to chime in?
I am new to Django have background in Node.js.
I am creating an API using Django, Django rest framework and PostgreSQL.
# Model for Event.
class Event(models.Model):
heading = models.TextField()
event_posted_by = models.ForeignKey(
CustomUser, on_delete=models.CASCADE, related_name='events_posted', null=True)
event_construction_site = models.ForeignKey(
ConstructionSite, on_delete=models.CASCADE, related_name='construction_site_events', null=True)
def __str__(self):
return str(self.id)
# Event ViewSet
class EventViewSet(viewsets.ModelViewSet):
queryset = Event.objects.all()
serializer_class = EventSerializer
# Event Serializer
class EventSerializer(serializers.ModelSerializer):
event_construction_site = ConstructionSiteShortSerializer()
event_posted_by = CustomUserSerializer()
class Meta:
model = Event
fields = ('id', 'heading',
'event_posted_by', 'event_construction_site')
Everything here works fine and expected as well.
Here is the output of my GET Request.
{
"id": 2,
"heading": "ABCD",
"event_posted_by": {
"id": 1,
"email": "abcd#gmail.com",
"first_name": "A",
"last_name": "B",
"profile_picture": "...",
"company": {
"id": 3,
"name": "Company 3"
},
},
"event_construction_site": {
"id": 2
}
},
But now when it comes to create an event this is the view django rest framework shows me.
{
"heading": "",
"event_posted_by": {
"email": "",
"first_name": "",
"last_name": "",
"company": {
"name": ""
},
"profile_picture": "",
"user_construction_site": []
},
"event_construction_site": {}
}
Here as far as I know when need "event_posted_by" by in GET Request but we don't want to post the user info. while creating an event, same for information inside user like user_construction_site here the only behaviour I want is to send the User ID to backend and somehow in my class EventViewSet(viewsets.ModelViewSet) handle this post request and map "event_posted_by" to user data by using user ID sent from client side.
How these kind of problems are genrally handeled in DRF by creating different read / write serailizers?
I managed to resolve the problem by following suggestion by #BriseBalloches in the comment above.
In summary updated the event_posted_by by adding a read_only key.
event_posted_by = UserSerializer(read_only=True)
I am using legacy DB tables that I have no control over the tables design.
Table A has an auto_gen ID field as follows:
Table DRAWER (One Side), Table FOLDER (Many Side)
class Drawer(models.Model):
id = models.PositiveIntegerField(primary_key=True, db_column='ID')
fld1 = models.CharField(max_length=1000, db_column='FLD1')
fld2 = models.CharField(max_length=1000, db_column='FLD2')
fld3 = models.CharField(max_length=1000, db_column='FLD3')
def __str__(self):
field_values = []
for field in self._meta.get_fields():
field_values.append(str(getattr(self, field.name, '')))
return ' '.join(field_values)
class Meta:
managed = False
db_table = u'"MySchema"."DRAWER"'
class Folder(models.Model):
id = models.PositiveIntegerField(primary_key=True, db_column='ID')
fld1 = models.CharField(max_length=1000, db_column='FLD1')
fld4 = models.CharField(max_length=1000, db_column='FLD4')
fld5 = models.CharField(max_length=1000, db_column='FLD5')
drawer = models.ForeignKey(to=Drawer, related_name='Drawer.fld1+', on_delete=models.CASCADE, db_constraint=False)
def __str__(self):
field_values = []
for field in self._meta.get_fields():
field_values.append(str(getattr(self, field.name, '')))
return ' '.join(field_values)
class Meta:
managed = False
db_table = u'"MySchema"."FOLDER"'
The ID fields are numeric auto gen. I am trying to use Djano models to establish a one to many relation between Tables DRAWER and FOLDER using fld1. fld1 is unique in Drawer, and many in Folder. I have done this in Java, but so far, it seems that Django won't allow it. Django seems to expect that one side must be a PK? I do realize that Django has many to one (instead of one to many) and followed the documentations ... but it is not working. Please advise if there is a way to do this in Django models framework.
The end result I am looking for in the rest service is something like below, which is what I get from the current JAVA Hibernate Data Rest Service:
{
"ID": 1234,
"FLD1": "xxxxxxxx",
"FLD2": "wertt",
"FLD3": "rtyuio",
folder:[
{
"ID": 5645,
"FLD1": "xxxxxxxx",
"FLD4": "zzzzzzz",
"FLD5": "cccccccc",
},
{
"ID": 5645,
"FLD1": "xxxxxxxx",
"FLD4": "rrrrrrr",
"FLD5": "cccccuuuuuuuuuuccc",
}
.
.
]
I appreciate any help that you can provide.
I'm trying to directly test my client code (with requests module) to call my Django API.
However, I want to automate this.
What I'm trying to do is create a model with test server running.
How am I able to populate my testdb with fixtures if one of my models has a ForeignKey?
class Customer(models.Model):
name = models.CharField(max_length=150)
phone = models.CharField(max_length=12)
email = models.CharField(max_length=250)
class Load(models.Model):
load_id = models.CharField(max_length=100, blank=True)
invoice_id = models.CharField(max_length=100, blank=True)
>customer = models.ForeignKey(Customer, on_delete=models.CASCADE, blank=True, null=True)
notes = models.CharField(max_length=500, blank=True)
carrier = models.ForeignKey(Carrier, on_delete=models.CASCADE, null=True, blank=True)
driver = models.ForeignKey(Driver, on_delete=models.CASCADE, null=True, blank=True)
active = models.BooleanField(default=True)
Edit: I linked the doc pertaining to this question. https://docs.djangoproject.com/en/dev/howto/initial-data/
Per the docs it has the following:
[
# I added the myapp.Band as an example of my issue
{
"model": "myapp.Band",
"pk": 1,
"fields": {
"band_name": "The Beatles"
}
},
{
"model": "myapp.person",
"pk": 1,
"fields": {
"first_name": "John",
"last_name": "Lennon"
}
},
{
"model": "myapp.person",
"pk": 2,
"fields": {
"first_name": "Paul",
"last_name": "McCartney"
# "band": ??? how would I assign?
}
}
]
Have you tried looking at Natural Keys: https://docs.djangoproject.com/en/dev/topics/serialization/#natural-keys
If you have the fixture created, update your database settings and run the loaddata command to load the fixture to the database.
Fixtures are often over-rated compared to using Factoryboy and Faker to generate test objects, including large batches of them for testing list-views and Django-filter views. I found this article extremely helpful in explaining how to combine them. The pain with fixtures comes when you add or remove fields from your models and forget to regenerate your fixtures. Or worse, if you leak information that really shouldn't have been made publicly accessible.
One warning - don't test factories from the manage.py shell. They automatically save the objects they generate! Instead write a test to test the factories. To avoid this mistake I put all my factories in one pseudo-app called fakery and in the __init.py__ file above the factory codes,
import sys
if len( sys.argv) >= 2 and sys.argv[1].find('shell') >= 0:
print("\nWARNING -- don't forget that Factories will save all objects they create!\n")
so if you import any of them into a shell, you see a warning.
How should I store parameters for application configuration?
For example. I've application for calculation of taxes in my project. There is few values I need to save once for long time without changes but with possibility to edit them(taxes, payment commissions, etc). Should I create some config.py file or create model config? Maybe there is other way.
If you want to configurate parameters in some calculation, I would go with model object and initial fixture. Because it's stored in database, you can change it anytime.
For example:
class Setting(models.Model):
key = models.CharField(max_length=255, blank=False, null=False, unique=True)
value = models.IntegerField(blank=False, null=False)
description = models.TextField(blank=True, null=True)
def __str__(self):
return self.key
and fixture (https://docs.djangoproject.com/en/1.9/howto/initial-data/):
[
{
"model": "myapp.setting",
"pk": 1,
"fields": {
"key": "[SOME_PARAMETER_KEY]",
"value": "[some value]",
"description": "[some description]"
}
}
]