简体   繁体   English

如何在 Django 中一起实现 unique

[英]How to implement unique together in Django

im working on a sales team project where i'm trying to implement a function to upload their daily visit plan.我正在从事一个销售团队项目,我正在尝试实施 function 以上传他们的日常访问计划。 While uploading i want to put a validation that, if visit for one customer is already uploaded then for same another wouldn't be uploaded and would raise a error like" Visit plan for this customer already exists on this date".在上传时,我想验证一下,如果已经上传了一个客户的访问,那么不会上传另一个客户,并且会引发错误,例如“该客户的访问计划在该日期已经存在”。 I have read some where that unique together would help me to validate but im not sure how to use unique together in View.我已经阅读了一些独特的在一起可以帮助我验证的地方,但我不确定如何在 View 中一起使用独特的。 please find the below codes for your reference and help.请找到以下代码供您参考和帮助。 Thanks in advance提前致谢

Model: Model:

class BeatPlan(models.Model):
beat_id = models.CharField(unique=True, max_length=15, null=True)
beat_dealer = models.ForeignKey(Dealer, null=True, on_delete=models.SET_NULL)
beat_user = models.ForeignKey('account.CustomUser', null=True, on_delete=models.SET_NULL)
beat_stake_holder = models.ForeignKey(StakeHolder, null=True, on_delete=models.SET_NULL)
beat_date = models.DateField(null=True)
create_date = models.DateField(null=True)
beat_status = models.CharField(choices=(('Not visited', 'Not visited'), ('Visited', 'Visited')),
                               default='Not visited', max_length=40, null=True)
beat_location = models.CharField(max_length=200, null=True)
beat_type = models.CharField(choices=(('Not planned', 'Not planned'), ('Planned', 'Planned')), max_length=50,
                             null=True)
beat_reason = models.CharField(max_length=200, null=True)

class Meta:
    unique_together = ('beat_date', 'beat_dealer')

def __str__(self):
    return str(self.beat_user) + str(self.beat_dealer) + str(self.beat_date)

View:看法:

def upload_beat(request):
global u_beat_dealer, beat_user_id, beat_date
template = "upload_beat.html"
data = BeatPlan.objects.all()
l_beat = BeatPlan.objects.last()
l_beat_id = l_beat.id
print(l_beat_id)
current_month = datetime.datetime.now().strftime('%h')
# prompt is a context variable that can have different values      depending on their context
prompt = {
    'order': 'Order of the CSV should be name, email, address,    phone, profile',
    'profiles': data
}
# GET request returns the value of the data with the specified key.
if request.method == "GET":
    return render(request, template, prompt)
csv_file = request.FILES['file']
# let's check if it is a csv file
if not csv_file.name.endswith('.csv'):
    messages.error(request, 'THIS IS NOT A CSV FILE')
data_set = csv_file.read().decode('UTF-8')
# setup a stream which is when we loop through each line we are able to handle a data in a stream
io_string = io.StringIO(data_set)
next(io_string)
for column in csv.reader(io_string, delimiter=',', quotechar="|"):
    u_beat_user_id = column[0]
    u_beat_dealer = column[1]
    beat_date = column[2]
    print(u_beat_user_id)
    if StakeHolder.objects.filter(unique_id=u_beat_user_id).exists():
        user_id = StakeHolder.objects.get(unique_id=u_beat_user_id)
        beat_user_id = user_id.id
        if Dealer.objects.filter(dealer_code=u_beat_dealer).exists():
            dealer_id = Dealer.objects.get(dealer_code=u_beat_dealer)
            u_beat_dealer = dealer_id.id
            l_beat_id += 1
            u_beat_id = current_month + str(l_beat_id)
            newBeatPlan = BeatPlan(beat_id=u_beat_id, beat_dealer_id=u_beat_dealer,
                                   beat_stake_holder_id=beat_user_id,
                                   beat_date=beat_date)
            newBeatPlan.save()
            messages.success(request, ' Beat added')

        else:
            messages.error(request, 'Dealer id does not exists')
    else:
        messages.error(request, "Unique ID doesn't exists")

context = {'beat_user': beat_user_id, 'dealer_code': u_beat_dealer, 'visit_date': beat_date}
return render(request, template, context)

Template:模板:

{% extends 'base.html' %}
{% load static %}

{% block content %}
<h3 style="margin-left: 10px">Upload Beat</h3>
<div class="row" style="margin-left: 5px">
    <div class="col-md-6">
        <hr>
        {{ order }}
        <form action="" method="POST" enctype="multipart/form-data">
            {% csrf_token %}
            <label for="file1"> Upload a file</label>
            <input type="file" id="file1" name="file" required><br><br><br><br><br>
            <small>Only accepts CSV files</small>
            <button class="btn btn-primary if-error-not-found" type="submit" 
  name="submit">Upload</button>
            <a href="{% url 'beatplan' %}">
                <div class="btn btn-primary back-button">Back</div>
            </a>
        </form>
        <br>
        <br>
    </div>

unique_together validates the data that is saved on the database. unique_together 验证保存在数据库中的数据。 However, you can still submit forms where those 2 fields are not unique and get an error on your backend.但是,您仍然可以提交 forms 这两个字段不是唯一的并且在您的后端出现错误。 What you need to do is to handle that error manually.您需要做的是手动处理该错误。 Django forms have a method add_error(field, error). Django forms 有一个方法 add_error(field, error)。 However, as I see, you do not use them, so you can just add an error parameter while rendering your template.但是,正如我所见,您不使用它们,因此您可以在渲染模板时添加一个错误参数。 Manually check if the customer has an input for that date, and add that error without saving anything to your database.手动检查客户是否有该日期的输入,并添加该错误而不将任何内容保存到您的数据库中。 Must look like this.一定是这个样子。

context['error'] = false
if YourModel.objects.filter(fields1=field1, field2=field2).exists():
     # your code that does not save anything
     context['error'] = true
     return render(request, template, context)

And handle the error on your template however you want.并根据需要处理模板上的错误。 unique_together will make sure that whatever you do, invalid data is not saved, so keep it. unique_together 将确保无论您做什么,都不会保存无效数据,因此请保留它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM