Save OneToManyRelationship based on url input in Django - python

I have two database which are OneToManyRelationship as shown below.
I am preparing interface for Data to be uploaded.
I want to specify the project attribute in Data model by inputting the url of the Project path like http://project/13.
Does anyone know how I can construct the relationship from url input of parent data?
Models.py
class Project(models.Model):
project = models.CharField(max_length=50, blank=True)
version = models.IntegerField(default=0)
class Data(models.Model):
project=models.ForeignKey(project)
csv=models.FileField(upload_to=dir_path)

If url in Project model sits in project field then you can do something like
# since project attribute is not unique, several ones can match so we pick first
project_object = Project.objects.filter(project=url).first()
if not project_object:
# error cant find it
Data.objects.create(
project=project_object,
csv=...,
)

Related

Wagtail models.py: How to create Custom folder in Media?

In Wagtail, How to add custom folder in Media and sync it into the database (Example) ?
NOTE: The Wagtail's Collection function is good, but for more than 1000 images/documents into a single folder will be pretty awkward to manage for I in the future (Ex: migration,...), so there is nothing to mention about Collection function in this question.
# If in Django (models.py) works:
class post(models.Model):
img = models.ImageField(upload_to='posts')
# So how in Wagtail (models.py) works:
class Posts(models.Model):
img = models.ForeignKey(
"wagtailimages.Image",
👉🏽 upload_to='posts', # How to add this line correctly ?
on_delete=models.SET_NULL,
null=True,
blank=False,
related_name="+",
)
Idea for Media Folder in Wagtail:
Media
authors
images
original_images
posts
images
original_images
...
If you want specific folders for specific models, you can set a specific folder by customizing the upload_to attribute in the model. Otherwise, the only option I know is to create collections.

How do I perform string actions on some CharField() or TextField right there in the model definition?

I am working on one of my first Django projects and on one of the models, I needed a field that returns a list that I can loop through and use in my templates. I have been trying to make it happen right there in models.py because I learned from the tutorials that it is best to perform all data manipulation or logic in the models file and nothing of such should be done in the templates as the template is just for rendering already parsed data.
I tried:
class Profile():
'''More user information.'''
user = models.ForeignKey(User, on_delete=models.CASCADE)
user.first_name = models.CharField(max_length=25)
user.last_name = models.CharField(max_length=25)
interests = models.CharField(max_length=200)
user.interests = [interest.strip() for interest in interests.split(',')]
In the code snippet above, I tried splitting comma separated values input by the user to try and make a list of it but I got the error:AttributeError: 'TextField' object has no attribute 'split'. Since the models.Charfield() and models.TextField() don't return a string, how do I go about this?
I use the sqlite db on my local.
The user model already has first_name and last_name so you can remove
If you want your user model to have the property interest you need to user custom user model
For performing an action on a field before saving it example you splitting the interests you can override the save method for the model

How To Separate Objects In Django Admin?

I have an app called 'Product' with the following models.py:
class Product(models.Model):
product_id = models.CharField(max_length=50)
pub_date = models.DateTimeField(default=datetime.now)
title = models.CharField(max_length=255)
price = models.DecimalField(max_digits=8, decimal_places=2)
user = models.ForeignKey(User, on_delete=models.CASCADE)
featured = models.BooleanField(default=False)
I want to have two separate sections in Django Admin: Products and Featured Products, depending if featured = True or False.
So by default all products are listed under the Products section. But if featured = True they will be moved to Featured Products section. Can you please help me how to do that? Thanks in advance.
Three steps:
Write a proxy model for model Product.
Change the default manager to only returns featured products.
Register your proxy model in the admin like any other model.
You can read more about it here: Using Proxy Models to Customize the Django Admin
There are a couple of ways to do this. The simplest perhaps is to create a database view, and then encapsulate it using a django model. You can create a view like so in your database console:
CREATE VIEW view_name AS
SELECT columns
FROM tables
[WHERE conditions];
Once you have done that, you can reference the view in django like so:
class FeaturedProduct(modes.Model):
attr1 = models.CharField()
class Meta:
managed = False
db_table = '<name of your view here>'
Make sure that managed is set to False. Here is the relevant documentation for that. You want to do that because django is not creating this model for you, but rather you are creating it yourself.
Another way to do this would be to create a custom Manager. These managers allow you to modify the objects attribute of your model, allowing you to set a queryset that you want. I think you'd want to take a look at the Manager documentation and you can take a look at defining custom querysets for your objects.

Extracting specific data field from Django Rest Framework api

I've recently complete the Django Rest Framework api tutorial and am having a difficult time understanding specifically how it's used as a backend for an application I plan to develop (this is my first venture into backend development). To put more simply, I don't understand how querying will work from the front end. Navigating through the api with either the browser or httpie makes sense, but I'm at a loss for how a frontend extracts specified data from a model.
For example, let's say I have the following:
Models
class Snippet(models.Model):
created = models.DateTimeField(auto_now_add=True)
title = models.CharField(max_length=100, blank=True, default='')
code = models.TextField()
linenos = models.BooleanField(default=False)
language = models.CharField(choices=LANGUAGE_CHOICES, default='python', max_length=100)
style = models.CharField(choices=STYLE_CHOICES, default='friendly', max_length=100)
highlighted = models.TextField()
Serializers
class SnippetSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Snippet
fields = ('id', 'title', 'code', 'linenos', 'language', 'style', 'url', 'highlight')
Views
class SnippetViewSet(viewsets.ModelViewSet):
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
If I'm a user on the other end of an application, how would I query 'language' inside of the Snippet model? How would I have access to whatever information is in 'language', and in what way would a frontend need to interact with my api to obtain this information?
My problem isn't necessarily how to build the api, but how to interact with it. Any help is greatly appreciated.
(Django 2.0, Python 3.5)
Ok, huge thanks to the Udemy course posted by Mark Winterbottom for the Django Rest Framework. I'll go ahead and leave this here for anybody else struggling with understanding some basic ideas in the Django Rest Framework.
JSON data is extracted by having the frontend hit urls determined by your api. So this becomes a question of "how do I implement some search functionality that's in a url?".
Django uses the Model, View, Controller pattern. A Model is what interacts with the database, and allows you to extract data from it without needing to understand how to query using actual SQL code (uses something called Object Relational Mapping to do this, or ORM, and your Models are in the model.py file). The Controller, how you interact with the pulled data to create/read/update/delete stuff in your api is saved in views.py (a bit counter intuitive, seeing as the View is what you would have in your templates folder [HTML pages and such]).
You can implement something called filters in your Controller (views.py) to allow you to search by specific information to get that ?search=whateveryouresearching url, by including the following:
from rest_framework import filters
and adding this to your ViewSet you want to search:
filter_backends = (filters.SearchFilter,) #allows for search functionality
search_fields = ('name','email') #which can be any Field in your viewset
This ?search=whateveryouresearching created by the filter is how some front end device will access specific searched information (such as a specific user input linke English or Mandarin inside 'language').

Retrieve Django rest framework related fields

Using the django-rest-framework is it possible to retrieve content from a related field. So for example I want to create a genre list which contains all projects within it. This is what I have but I keep on getting the error:
'Genre' object has no attribute 'project_set'
models.py
class Genre(models.Model):
name = models.CharField(max_length=100, db_index=True)
class Project(models.Model):
title = models.CharField(max_length=100, unique=True)
genres = models.ManyToManyField(Genre, related_name='genres')
serializers.py
class GenreSerializer(serializers.ModelSerializer):
project_set = serializers.ManyRelatedField()
class Meta:
model = Genre
fields = ('name', 'project_set')
The related name you're using on the Project class is badly named. That related name is how you access the set of projects related to a given genre instance. So you should be using something like related_name='projects'. (As it is you've got it the wrong way around.)
Then make sure that your serializer class matches up with the related name you're using, so in both places project_set should then instead be projects.
(Alternatively you could just remove the related_name='genres' entirely and everything will work as you were expecting, as the default related_name will be 'project_set'.)

Categories