how to have database relationship with the active data. in django - django

i have some active and non active data's in EVENT models and active data has the VISITORS form to fill ..so far i have tried OnetoOne relationship but it didn't succeed ..i am getting both active and non active field in VISITORs model..thank you for your time.
here is models.py
class Event(models.Model):
event_id = models.AutoField
Event_Name = models.CharField(max_length=50)
description = RichTextField()
date_And_time = models.DateTimeField()
location=models.CharField(max_length=50)
slugs = models.SlugField(max_length= 200,default="")
picture = models.ImageField(upload_to='wildlife/picture', default="")
active = models.BooleanField(default=False)
class Meta:
ordering = ["date_And_time"]
def __str__(self):
return self.Event_Name
class Eventvisitor(models.Model):
event = models.OneToOneField(Event, on_delete=models.CASCADE, related_name="eventvistor",default="")
name = models.CharField(max_length=50)
email = models.CharField(max_length=70, default="")
phone = models.CharField(max_length=20,default="")
date = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ['-date']
def __str__(self):
return self.email

You can limit the choices with limit_choices_to=… [Django-doc]. But likely what you want is a ForeignKey, since otherwise, each Event can have at most one related EventVisitor (a OneToOneField is basically a ForeignKey with a unique=True constraint).
class Eventvisitor(models.Model):
event = models.ForeignKey(
Event,
limit_choices_to={'active': True},
on_delete=models.CASCADE,
related_name='eventvistors'
)
name = models.CharField(max_length=50)
email = models.CharField(max_length=70, default="")
phone = models.CharField(max_length=20,default="")
date = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ['-date']
def __str__(self):
return self.email
Note that while one can only select Events with active=True, if you later set the .active field to False, items will still link to it, since the relation is not enforced at database level.

Related

Need Help in django form widgets

I am in a middle of a project. I need help in using widgets. I have a Model for which i want a model form :
My model is :
class Appointments(models.Model):
doctor = models.ForeignKey(Doctor, on_delete=models.CASCADE)
patient = models.ForeignKey(Patient, on_delete=models.CASCADE)
app_time = models.DateTimeField()
diognoses = models.TextField(max_length=1000, null=True, blank=True)
prescriptions = models.TextField(max_length=250, null=True, blank=True)
class Meta:
unique_together = ('doctor', 'patient', 'app_time')
def __str__(self):
st = str(self.patient.user.name)+str(self.doctor.user.name)
return st
The corresponding model form is :
class AppointmentBookForm(forms.ModelForm):
app_time = forms.DateTimeField(widget=forms.SplitDateTimeWidget())
class Meta:
model = Appointments
fields = ['doctor','app_time']
Now for app_time I have split the date and time field which is already working fine.
Now I want a dropdown for date and a suitable widget for time.
The time should contain only hours and minutes.
And Finally I also want to provide the options for timing depending on the date and doctor.
For plain html the easiest way might be to define two input fields, one for the time and one for the date.
Input type="date":
https://www.w3schools.com/tags/att_input_type_date.asp
Input type="time":
https://www.w3schools.com/tags/att_input_type_time.asp
There are multiple results to this, here is one proposal:
models.py
from datetime import datetime
class Appointments(models.Model):
doctor = models.ForeignKey(Doctor, on_delete=models.CASCADE)
patient = models.ForeignKey(Patient, on_delete=models.CASCADE)
time = models.TimeField()
date = models.DateField()
app_time = models.DateTimeField()
diognoses = models.TextField(max_length=1000, null=True, blank=True)
prescriptions = models.TextField(max_length=250, null=True, blank=True)
def save(self, *args, **kwargs):
self.app_time = datetime.combine(self.date, self.time)
super().save(*args, **kwargs)
class Meta:
unique_together = ('doctor', 'patient', 'app_time')
def __str__(self):
st = str(self.patient.user.name)+str(self.doctor.user.name)
return st
forms.py
class AppointmentBookForm(forms.ModelForm):
class Meta:
model = Appointments
fields = ['doctor', 'time', 'date']
"""
# Optional: Define dedicated types or classes for the single fields
widgets = {
'time': forms.DateField(attr={"class": "myclass", "type": "time"})
}
"""
The app_time is quite redundant in this case. You could also define a property to receive the datetime:
class Appointments(models.Model):
doctor = models.ForeignKey(Doctor, on_delete=models.CASCADE)
patient = models.ForeignKey(Patient, on_delete=models.CASCADE)
time = models.TimeField()
date = models.DateField()
diognoses = models.TextField(max_length=1000, null=True, blank=True)
prescriptions = models.TextField(max_length=250, null=True, blank=True)
#property
def app_time(self):
return datetime.combine(date, time)
class Meta:
unique_together = ('doctor', 'patient', 'time', 'date')
def __str__(self):
st = str(self.patient.user.name)+str(self.doctor.user.name)
return st
example:
appointment = Appointments.objects.first()
print(appointment.app_time)
Alternatively, use some nice front end framework if you want to keep a single datetimefield.

how to use django Serializer or signal to add object in database?

I create ticket , ticketflow , ticketstate , tickettype models
i need a serializer or signal that when user create ticket programmatically add ticketflow object and set state of ticket to submited or something else
Here is my models
class TicketType(models.Model):
title = models.CharField(max_length=255, blank=False, unique=True, null=False)
def __str__(self):
return self.title
class TicketState(models.Model):
title = models.CharField(max_length=255, blank=False, unique=True, null=False)
def __str__(self):
return self.title
class Ticket(models.Model):
id = models.UUIDField(primary_key=True, default=uuid4 , editable=False)
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete= models.CASCADE)
ticket_type = models.ForeignKey(TicketType,on_delete=models.CASCADE , default=1)
title = models.CharField(max_length=255, blank=False, null=False)
message = models.TextField()
attachment = models.FileField(upload_to='uploads/tickets/', validators=[FileExtensionValidator(allowed_extensions=['pdf','docx','zip','jpg','png'])], blank=True)
created_on = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ['-created_on']
def __str__(self):
return self.title
class TicketFlow(models.Model):
uuid = models.UUIDField(default=uuid4, editable=False)
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete= models.CASCADE)
ticket = models.ForeignKey(Ticket,on_delete=models.CASCADE , related_name='ticketflow')
ticket_state = models.ForeignKey(TicketState,on_delete=models.CASCADE , default=1 , related_name='ticketstate')
message = models.TextField()
attachment = models.FileField(upload_to='uploads/tickets/', validators=[FileExtensionValidator(allowed_extensions=['pdf','docx','zip','jpg','png'])], blank=True)
created_on = models.DateTimeField(auto_now_add=True)
updated_on = models.DateTimeField(auto_now= True)
class Meta:
ordering = ['-created_on']
here is my serializers
class TicketTypeSerializer(serializers.ModelSerializer):
class Meta:
model = TicketType
fields = ('id','title',)
class TicketStateSerializer(serializers.ModelSerializer):
class Meta:
model = TicketState
fields = ('id','title',)
class TicketSerializer(serializers.ModelSerializer):
class Meta:
model = Ticket
fields = ['id' , 'author', 'ticket_type','title' ,'message' , 'attachment' , 'created_on']
class TicketFlowSerializer(serializers.ModelSerializer):
class Meta:
model = TicketFlow
fields = ['author', 'ticket_state', 'message', 'attachment', 'created_on', 'updated_on']
It'll be great if someone can help me out in this. how can i create signal or override create method in serializers
You probably want your "state" field to be read-only in the serializer, this way it can only be changed programmatically, and in the model set a default value with default='pending'.
Then you can override the update method in a Serializer (see the doc here):
def update(self, instance, validated_data):
validated_data['state'] = 'edited'
return super(MySerializer, self).update(instance, validated_data)

drf create manytomany fields

models
class CreatorRawArtwork(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=500)
descripton = models.TextField()
editions = models.IntegerField(null=True, blank=True)
price = models.CharField(max_length=500)
created_at = models.DateTimeField(auto_now_add=True, null=True, blank=True)
medias = models.FileField(null=True, blank=True, upload_to="raw-medias")
user = models.ForeignKey(to=Login, on_delete=models.CASCADE, related_name="creatorrawartwork", null=True, blank=True
)
collection = models.ForeignKey(
to=DesignerCollection, on_delete=models.CASCADE, related_name="creatorrawartwork", null=True, blank=True)
categories = models.ManyToManyField(DesignerCategories, related_name='creatorrawartwork')
def __str__(self):
return self.title
serializer
class CreatorRawArtworkSerializer(serializers.ModelSerializer):
categories = serializers.PrimaryKeyRelatedField(queryset=DesignerCategories.objects.all(), many=True)
class Meta:
model = CreatorRawArtwork
fields = "__all__"
depth=1
views
class CreatorRawArtworkView(viewsets.ModelViewSet):
queryset = CreatorRawArtwork.objects.all()
serializer_class = CreatorRawArtworkSerializer
Here i am trying to create manytomany fields using drf serialier it is showing some error
plese check the screenshot for parameter and responses
What can be the issue please take a look
class CreatorRawArtworkSerializer(serializers.ModelSerializer):
collection = DesignerCollectionSerializer(read_only=True) #assuming you have already defined serializer for *DesignerCollectionSerializer*
categories = DesignerCategoriesSerializer(many=True)
class Meta:
model = CreatorRawArtwork
fields = "__all__"
depth=1
I tested with your code and your code is working fine
just make sure your request data is json

Simple django filter is includes all users’ data rather than that of the logged-in user

I’m new to Django and have built a basic filter that does not filter according to the logged-in user’s data but rather all users’ data, which is incorrect. The filter is for an Automation class, which has a many:many relationship with the Message class (and funnily enough the exact same happens with the message filter).
Views.py:
#login_required(login_url='login')
#allowed_users(allowed_roles=['admin', 'customer'], own_account_only=True)
def automation_list(request, pk):
account = Account.objects.get(id=pk)
automations = account.automation_set.all()
filter = AutomationFilter(request.GET, queryset=automations)
automations = filter.qs
context = {'account': account,
'automations': automations, 'filter': filter}
return render(request, 'automations/automation_list.html', context)
Filters.py:
class AutomationFilter(django_filters.FilterSet):
start_date = DateFilter(field_name='date_joined', lookup_expr='gte')
end_date = DateFilter(field_name='date_joined', lookup_expr='lte')
class Meta:
model = Automation
fields = '__all__'
exclude = ['account', 'date_created']
Models:
class Automation(models.Model):
name = models.CharField(max_length=100)
description = models.CharField(max_length=200)
account = models.ForeignKey(Account, on_delete=models.CASCADE)
date_created = models.DateTimeField(auto_now_add=True, null=True)
messages = models.ManyToManyField(Message, blank=True)
def __str__(self):
return self.name
class Message(models.Model):
name = models.CharField(max_length=100)
subject = models.CharField(max_length=128)
text = models.TextField()
account = models.ForeignKey(Account, on_delete=models.CASCADE)
date_created = models.DateTimeField(auto_now_add=True, null=True)
automations = models.ManyToManyField('automations.Automation', blank=True)
def __str__(self):
return self.name
Why is the filter not just filtering according to the logged-in user? I’d have thought that I’m only passing in the user’s data via this line:
filter = AutomationFilter(request.GET, queryset=automations)
Thanks

Create relationship between two models using django class based views

I have two models Company and Campaign. I need to create a relationship between them. I think my models are fine.
companies/model.py
class Company(models.Model):
class Meta:
verbose_name_plural = "companies"
user = models.ForeignKey(settings.AUTH_USER_MODEL)
title = models.CharField(blank=False, max_length=128, default='')
slug = models.SlugField(blank=True, unique=True)
archived = models.BooleanField(default=False)
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
campaigns/models.py
class Campaign(models.Model):
class Meta:
verbose_name_plural = "campaigns"
company = models.ForeignKey('companies.Company', on_delete=models.CASCADE,)
title = models.CharField(blank=False, max_length=128, default='')
slug = models.UUIDField(default=uuid.uuid4, blank=True, editable=False)
def __str__(self):
return str(self.title)
campaigns/forms.py
class CampaignForm(forms.ModelForm):
class Meta:
model = Campaign
fields = ['title','description','archived']
campaigns/views.py
class CampaignCreateView(SubmitBtnMixin, CreateView):
model = Campaign
company = None
form_class = CampaignForm
submit_btn = "Add Campaign"
template_name = "form.html"
campaigns/urls.py
url(r'^campaign/create/$', CampaignCreateView.as_view(), name='campaign-create'),
My question is, when creating a new campaign, where and how do I pick up the Company pk to populate the Campaign model? What is the most secure and best practice for doing this?
I found a solution but would like input on best practices still.
I added this to my CampaignCreateView
def form_valid(self, form):
company = get_object_or_404(Company, id=self.kwargs.get('pk'), user_id=self.request.user.id)
form.instance.company_id = company.id
return super(CampaignCreateView, self).form_valid(form)
and I changed my url to:
url(r'^campaign/(?P<pk>\d+)/create/$', CampaignCreateView.as_view()...
Not sure that I like the pk in the URL since it can be jacked. This is why I am filtering on the userid at the company model to make sure that the data is coming from the owner.
I thought of doing this by registering the company in the session id but I am not convinced that sessions do not present their own problems.