This is how my model looks like. When ever user orders. The order id provided by django is simple. Its like 1,2,3 ..... 100.
class UserOrder(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='orders',
on_delete=models.CASCADE)
cart = models.ForeignKey(Cart, related_name="orders", on_delete=models.CASCADE, null=True,
blank=True)
date = models.DateTimeField(default=datetime.now)
total_price = models.IntegerField(null=True, blank=True)
note = models.TextField(null=True, blank=True)
cancel_reason = models.TextField(null=True, blank=True)
cancelled = models.BooleanField(default=False)
confirmed = models.BooleanField(default=False)
def __str__(self):
return self.user.username
Your question is not well defined but I think I understand your problem, you need a id (lookup field) that is not simple.
you can use uuid, and use this uuid for all the lookup in the viewsets, instead of the sequentially created id by django.
something like this lookup_field = 'uuid' in views.
import uuid
class UserOrder(models.Model):
uuid = models.UUIDField(default=uuid.uuid4, unique=True, db_index=True, editable=False)
read more about uuids here https://docs.python.org/3/library/uuid.html#uuid.uuid4
try using the django-random-id-model
run pip install django-random-id-model
in your django models.py file import RandomIDModel from django-random-id-model
then add RandomIdModel to your model class, in case this is:
class UserOrder(RandomIdModel):
#remaining codes here
Related
I'm using Django and I want to know how to get objects through 3 models
These are my models
class Participant(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
is_leader = models.BooleanField(default=False)
team = models.ForeignKey(Team, on_delete=models.CASCADE, null=True, related_name="participants")
application_date = models.DateField(auto_now_add=True, null=True)
resolution_date = models.DateField(null=True, blank=True)
accepted = models.BooleanField(default=False)
class Team(models.Model):
name = models.TextField(default="")
is_public = models.BooleanField(default=False)
institution = models.ForeignKey(Institution, on_delete=models.CASCADE, null=True, related_name='teams')
campaign = models.ForeignKey(Campaign, on_delete=models.CASCADE, null=True, related_name='teams')
class Campaign(models.Model):
name = models.TextField(default="")
description = models.TextField(default="")
initial_date = models.DateTimeField(auto_now_add=False, null=True, blank=True)
end_date = models.DateTimeField(auto_now_add=False, null=True, blank=True)
qr_step_enabled = models.BooleanField(default=True)
image_resolution = models.IntegerField(default=800)
sponsor = models.ForeignKey(Sponsor, on_delete=models.CASCADE, null=True, related_name='campaigns')
I have the user through a request, and I want to get all campaigns of that user.
I tried doing it with for loops but I want to do it with queries
this is what I had:
user = request.user
participants = user.participant_set.all()
for participant in participants:
participant.team.campaign.name
is there a way to make a query through these models and for all participants?
A user can have many participants, and each participant has a Team, each team has a campaign
The best way is to merge the two modela Team and Campaign in one model.
Something as simple as this should work:
Campaign.objects.filter(team__participant__user=request.user)
The Django ORM is smart enough to follow foreign key relationships in both directions.
Thanks to Daniel W. Steinbrook to guide me to the answer, I had to do this to get the query:
Campaign.objects.filter(teams__participants__user__exact=request.user)
My models:
class User(models.Model):
id = models.UUIDField(primary_key=True)
first_name = models.Charfield()
class Conversation(models.Model):
id = models.UUIDField(primary_key=True)
user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
class Message(models.Model):
id = models.UUIDField(primary_key=True)
conversation = models.ForeignKey(Conversation, on_delete=models.PROTECT, null=False)
text = models.TextField()
created_at = models.DateTimeField(auto_now_add=True, blank=True)
I tried to to order by adding annotate and adding order by. Can some body help me to select all users and order them by the latest message they had. I need user with latest message at to and then accordingly.
Try this
queryset = User.objects.all().order_by(
'-conversation__message__created_at'
).distinct()
I have a project in which some user can perform CRUD activities. I want to record who did what and when. Currently, I am thinking of making a model
class UserAction(models.Model):
user_id = models.CharField(max_length=100)
action_flag = models.CharField(max_length=100)
class_id = models.CharField(max_length=100)
action_taken_at = models.DateTimeField(default=datetime.now())
and making a function that fills my UserAction table. Is there any better way to do this?
app/models.py:
from django.db import models
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey
class Action(models.Model):
sender = models.ForeignKey(User,related_name='user',on_delete=models.CASCADE)
verb = models.CharField(max_length=255)
target_ct = models.ForeignKey(ContentType, blank=True, null=True,
related_name='target_obj', on_delete=models.CASCADE)
target_id = models.PositiveIntegerField(null=True, blank=True)
target = GenericForeignKey('target_ct', 'target_id')
created = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ('-created',)
def __str__(self):
return self.pk
app/admin.py
from .models import Action
admin.site.register(Action)
How you can use it ?
you can now import this models(Action) inside any of yours views.py.
Example if you have a post and a user likes it.you can just write
Action.objects.create(sender=request.user,verb="likes this post",target=post)
and now when you look at your admin you will see that tartget_id=post.pk
Here I assume that a user is authenticated and you can change it for your own.Happy coding!!!
You can do it by creating a model in
Models.py
class Auditable(models.Model):
ip = models.GenericIPAddressField(null=True)
user_agent = models.CharField(max_length=255, blank=True)
remote_host = models.CharField(max_length=255, blank=True)
created_at = models.DateTimeField(auto_now_add=True, blank=True, null=True)
created_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING, related_name="%(app_label)s_%(class)s_created_by", null=True, blank=True) # this is for web user
modified_at = models.DateTimeField(auto_now=True, blank=True, null=True)
modified_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING, related_name="%(app_label)s_%(class)s_modified_by", null=True, blank=True) # this is for web user
class Meta:
abstract = True
def get_fields(self):
list_fields = ['ip', 'user_agent',
'remote_host', 'created_by', 'modified_by']
return [(field.verbose_name, field._get_val_from_obj(self)) for field in self.__class__._meta.fields if field.name not in list_fields and not
(field.get_internal_type() == "DateTimeField" and
(field.auto_now is True or field.auto_now_add is True)) and
field.concrete and (not field.is_relation or field.one_to_one or
(field.many_to_one and field.related_model))]
You can give any class name (i have given auditable). So all you have to do is pass this class (auditable) in your every model instead of models.Model
For Eg:
class Student(Auditable):
By doing this it will add all the auditable fields records in every table you have created.
Hope you may get your answer by doing this.
E.g. there are next models and custom QuerySet:
from django.db import models
class ActiveQuerySet(models.QuerySet):
def active(self):
'''returns only active objects'''
'''supposing here would be a lot
of more complicated code
that would be great to reuse
'''
return self.filter(is_active=True)
class Category(models.Model):
name = models.CharField(max_length=128, blank=True, null=True, default=None)
class Product(models.Model):
name = models.CharField(max_length=128, blank=True, null=True)
is_active = models.BooleanField(default=True)
category = models.ForeignKey(Category, on_delete=models.SET_NULL, related_name='products', related_query_name="product", blank=True, null=True, default=None)
objects = ActiveQuerySet.as_manager()
Could you tell me if there is a way to call the active() method like this:
category = Category.objects.first()
category.products.active()
instead of doing like this:
category.products.filter(is_active=True)
Or how to implement appropriately such behavior?
You have to add the custom queryset into the parent model, not the _set. You can change custom_products to any other word.
class ActiveQuerySet(models.QuerySet):
def active(self):
'''returns only active objects'''
'''supposing here would be a lot
of more complicated code
that would be great to reuse
'''
return self.products.filter(is_active=True)
class Category(models.Model):
name = models.CharField(max_length=128, blank=True, null=True, default=None)
custom_products = ActiveQuerySet.as_manager()
category.custom_products.active()
I made some basic models for a listing of a business, like so:
class Business(models.Models):
id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=225, blank=True)
address = models.CharField(max_length=150, blank=True)
city = models.CharField(max_length=150, blank=True)
state_id = models.IntegerField(null=True, blank=True)
zip = models.CharField(max_length=33, blank=True)
country = models.CharField(max_length=150, blank=True)
url = models.CharField(max_length=765, blank=True)
class States(models.Model):
id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=96)
state_abbr = models.CharField(max_length=24, blank=True)
In the admin when I edit each business it shows the state_id field. But how do I connect it with the state model to show a select dropdown listing of the states?
Also, how do I show the state abbreviation in the view of a business?
An alternative that doesn't require a separate state table:
from django.contrib.localflavor.us.us_states import STATE_CHOICES
class Business(models.Models):
...
state = models.CharField(max_length=2, choices=STATE_CHOICES, null=True, blank=True)
...
Edit in 2015 (django 1.8)
you should check the django official localflavor repo: https://github.com/django/django-localflavor.
from localflavor.us.models import USStateField
class Business(models.Models):
…
state = USStateField(null=True, blank=True)
…
Some tests are available on the repo for this specific usage.
Docs available here.
You need to use a ForeignKey field.
Make the following changes.
class Business(models.Models):
id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=225, blank=True)
address = models.CharField(max_length=150, blank=True)
city = models.CharField(max_length=150, blank=True)
#state_id = models.IntegerField(null=True, blank=True)
# Define a new state field that creates a ForeignKey relationship with States
state = models.ForeignKey('States', null=True, blank=True)
zip = models.CharField(max_length=33, blank=True)
country = models.CharField(max_length=150, blank=True)
url = models.CharField(max_length=765, blank=True)
class States(models.Model):
id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=96)
state_abbr = models.CharField(max_length=24, blank=True)
#Define the __unicode__ method, which is used by related models by default.
def __unicode__(self):
return self.state_abbr
By default ForeignKey fields append '_id' to the field name when creating the column name in the database. So, the new "state" field in the Business class will automatically use the column "state_id" that you've previously defined, unless you've changed some of the default behavior of Django.
For more on this:
Check out Django's documentation of
the ForeignKey field
Search "ForeignKey" on stackoverflow.com