【问题标题】:Accept only some variables in form fields from CSV and not all in Django?只接受 CSV 表单字段中的一些变量,而不接受 Django 中的所有变量?
【发布时间】:2021-01-13 18:36:14
【问题描述】:

我有一个 Django 模型,其中包含 2 个字段作为纬度和经度。我已将它们都声明为 CharField。我的模型需要接受超过 1 个坐标(纬度和经度),因此在以渲染形式(在 UI 中)输入时,我输入这些坐标,用逗号分隔。正是这个 char 输入,然后我将其拆分为函数并进行计算..

这是我的models.py

class Location(models.Model):
    country = models.ForeignKey(Countries, on_delete=models.CASCADE)
    latitude = models.CharField(max_length=1000,help_text="Add the latitudes followed by comma")
    longitude = models.CharField(max_length=1000,help_text="Add the longitudes followed by comma")

这是我的 view.py 函数

def dashboard(request):
    form = LocationForm
    if request.method == 'POST':
        form = LocationForm(request.POST)
        if form.is_valid():
            form.save()
            latitude = list(map(float, form.cleaned_data.get('latitude').split(',')))
            longitude = list(map(float, form.cleaned_data.get('longitude').split(',')))
            .........
            .........
    return render(request, dashboard/dashboard.html, { 'form':form })

现在,我希望我的模型也接受坐标作为 CSV 文件。我想在 UI 中添加一个选项来添加一个 CSV 文件(具有多个纬度和经度),然后填充这两个字符字段(作为逗号分隔的值)。

请注意,我的 CSV 文件不会包含国家/地区名称。我将只使用表单 UI 进入该国家/地区。

因此,简而言之,我需要接受一些表单字段作为 CSV 文件,而不是全部。

我找到了上传 CSV 文件的解决方案,但它们都填充了所有模型字段,而不仅仅是选择性的。因此,CSV 文件必须包含所有表单字段值(在我的例子中也是国家)

我能做什么?也许,在模型中有一个 FileField() 并用它做点什么。或者我可以只使用 javascript 来填充 UI 中的坐标。或者其他的东西。

不知道该怎么办?

【问题讨论】:

    标签: javascript python-3.x django django-models django-forms


    【解决方案1】:

    https://docs.djangoproject.com/en/3.1/topics/http/file-uploads/#upload-handlers

    然后为您的表单类:

    # import csv
    # import codecs
    # form = LocationForm(data=request.POST, files=request.FILES)
    
    class LocationForm(forms.ModelForm):
        file = forms.FileField(required=False)
    
        class Meta:
            model = Location
            fields = ('file', 'country', 'latitude', 'longitude')  # this order matters
    
        def clean_file(self):
            if 'file' not in self.files:
                return
    
            file = self.files['file']
            reader = csv.reader(codecs.iterdecode(file, 'utf-8'))
            header = next(reader)
            latitudes = []
            longitudes = []
            for lat, long in reader:
                latitudes.append(lat)
                longitudes.append(long)
            self.data['latitude'] = ','.join(latitudes)
            self.data['longitude'] = ','.join(longitudes)
            return file
    

    这样做的好处是您对clean_latitude/clean_longitude 的任何验证仍然有效。

    如果你遇到困难,这是我的测试:https://gist.github.com/kingbuzzman/64a8ec7dd023f2195316c38b15c5ebbd#file-csv_upload-py-L143


    一些想法:

    1. 模型在 django 中是单数,重命名 Countries -> Country
    2. 为什么纬度/对数必须是CharFields?它们不能是小数位吗?您已经拥有从 LocationCountry 的正确关系(参见 #1),这意味着单个 Country 可以有多个 Locations,为什么要将所有地理点塞进一行?

    个人:我会从经度和纬度中删除CharField,并将类型更改为DecimalField。对每个字段运行验证,上传的 csv 文件将遍历每一行,并为每个国家/地区-经度-纬度组合创建一个新的 Location 实例。

    我应该说,我不知道你为什么要做你正在做的事情的原因,我是 100% 猜测。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-16
      • 1970-01-01
      • 1970-01-01
      • 2021-12-24
      • 2012-04-15
      相关资源
      最近更新 更多